123
4567
891011
digraph demo
2.1.1 線性表的定義
線性表是具有相同資料型別的$n(n \ge 0)$個元素的有限序列,其中$n$為表長
若用$l$命名線性表,則其一般表示為
$$l=(a_1,a_2,…,a_n)$$
線性表的邏輯特性
線性表的特點有
注意: 線性表是一種邏輯結構,表示元素之間的一對一的相鄰關係,順序表和煉表是指儲存結構,兩者屬於不同層面的概念,因此不要混淆
2.1.2 線性表的基本操作
資料結構的基本操作
線性表的主要操作
2.2.1 順序表的定義
線性表的順序儲存又稱順序表,它是用一組位址連續的儲存單元依次儲存線性表中的資料元素,從而使邏輯上相鄰的兩個元素在物理位置上也相鄰
順序表的特點是表中元素的邏輯順序與其物理順序相同
順序表支援隨機訪問,即通過首位址和元素序號可在時間$o(1)$內找到指定的元素
順序表的儲存密度高,每個節點除了資料元素外,不儲存其他多餘的值
順序表邏輯上相鄰的元素物理上也相鄰,所以插入和刪除操作需要移動大量元素
2.2.2 順序表上基本操作的實現
1 插入操作
123
4567
891011
1213
14
status listinsert(sqlist *l, int i, elemtype e)
if(l->length >= l->listsize && overflow == realloclist(l))
for(int j = l->length - 1; j >= i; j --)
l->elem[i] = e;
l->length++;
return ok;
}
插入操作的時間複雜度
2 刪除操作
123
4567
891011
1213
1415
//刪除元素
status listdelete(sqlist *l, int i, elemtype *e)
*e = l->elem[i];
printf("before: %d\n", e->id);
for(int j = i; j < l->length - 1; j ++)
l->length--;
printf("after: %d\n", e->id);
return ok;
}
刪除操作的時間複雜度
3 按值查詢
123
4567
891011
//按值查詢元素
status locateelem(sqlist *l, elemtype e, int *locate)
}*locate = -1;
return nosuchelem;
}
按值查詢的時間複雜度
鏈式儲存線性表時,不需要使用位址連續的儲存單元,即它不要求邏輯上相鄰的兩個元素在物理位置上也相鄰
它通過」鏈」建立起資料元素之間的邏輯關係,因此對於線性表的插入、刪除不需要移動元素,而只需要修改指標
2.3.1 單鏈表的定義
線性表的鏈式儲存又稱單鏈表,它是指通過一組任意的儲存單元來儲存線性表中的資料元素
為了建立資料元素之間的線性關係,對每個鍊錶節點,除存放元素本身的資訊外,還需要存放乙個指向其後繼的指標
單鏈表中節點型別的描述
123
4
typedef struct lnodelnode
非隨機儲存
頭指標和頭節點
頭節點和頭指標的區別
引入頭節點之後的優點
由於開始節點的位置被存在頭節點的指標域中,所以在鍊錶的第乙個位置上的操作與在表的其他位置上的操作一致,無須進行特殊處理
無論鍊錶是否為空,其頭指標都指向頭節點的非空指標
2.3.2 單鏈表上基本操作的實現
1 插入操作
123
4567
891011
1213
1415
1617
status listinsert(linkedlist *l, int i, elemtype e)
lnode *curr = l->head;
for(int j = 0; j < i; j ++)
lnode *p = (lnode *)malloc(sizeof(lnode));
p->elem = e;
printf("afterinsert: %d %s\n", p->elem.id, p->elem.name);
p->next = curr->next;
curr->next = p;
l->length++;
return ok;
}
時間複雜度: $o(n)$
擴充套件: 對某節點的前插操作
前插操作是指在某節點的前面插入乙個新節點,與後插操作相反
要找到插入節點的前驅節點,然後對這個節點執行後插操作
2 刪除操作
123
4567
891011
1213
1415
status listdelete(linkedlist *l, int i, elemtype *e)
lnode *curr = l->head;
for(int j = 0; j < i; j ++)
*e = curr->next->elem;//[正確寫法]
printf("delete: %d %s\n",e->id, e->name);
curr->next = curr->next->next;
l->length--;
return ok;
}
時間複雜度: $o(n)$
擴充套件:刪除節點*p
3 按序號查詢操作
123
4567
891011
1213
//按位置查詢元素
status getelem(linkedlist *l, int i, elemtype *e)
lnode *curr = l->head->next;
for(int j = 0; j < i; j ++)
*e = curr->elem;
return ok;
}
時間複雜度$o(n)$
4 按值查詢操作
123
4567
891011
1213
14
status locateelem(linkedlist *l, elemtype e, int *locate)
i ++;
}*locate = -1;
return nosuchelem;
}
時間複雜度: $o(n)$
2.3.3 雙鏈表
雙鏈表節點中有兩個指標prior
和next
分別指向前驅節點和後繼節點
2.3.4 迴圈鍊錶
1 迴圈單鏈表
迴圈單鏈表和單鏈表的區別是,表中最後乙個節點的指標不是null
,而是改為指向頭節點,從而整個鍊錶形成乙個環
有時對單鏈表常做的操作是在表頭和表尾進行的,此時對迴圈單鏈表不設頭指標而僅設尾指標,從而效率更高,對表頭和表尾進行操作都是$o(1)$
2 迴圈雙鏈表
略2.3.5 靜態鍊錶
靜態鍊錶是借助陣列來描述線性表的鏈式儲存結構
節點也有資料域data
和指標域next
,但是,這裡的指標是節點的相對位址(陣列下標)
靜態鍊錶結構型別如下
123
45
#define maxsize 50
typedef structslinkedlist[maxsize];
靜態鍊錶以next == -1
為結束標誌
總體來說,靜態鍊錶沒有單鏈表使用起來方便
2.3.6 順序表和煉表的比較
1 訪問方式
順序表可以順序訪問,也可以隨機訪問,鍊錶只能從表頭順序訪問元素
2 邏輯結構與物理結構
採用順序儲存時,邏輯上相鄰的元素,其對應的物理儲存位置也相鄰
採用鏈式儲存時,邏輯上相鄰的元素,其物理儲存位置不一定相鄰
3 查詢、插入和刪除操作
按值查詢操作
按位置查詢
插入和刪除
4 空間分配動態儲存
5 如何選擇儲存結構
基於儲存考慮
基於運算考慮
基於環境考慮
考研資料結構 線性表
線性表是具有相同特徵資料元素的乙個有限序列。元素個數叫做線性表的長度,n n 0 表示,n 0 空表 只有乙個表頭元素,只有乙個表尾元素。表頭無前驅,表尾無後繼,除表頭和表尾外,其他元素只有乙個直接前驅,也只有乙個直接後繼。順序儲存結構 順序表 和鏈式儲存結構 鍊錶 兩種。順序表 連續儲存 順序儲存...
資料結構考研複習 線性表2
2 廈門大學 2000 15分 有序線性表的合併 這個比較基礎,例如給出兩個鍊錶,h1 1 3 5 7 9 h2 0 2 4 合併的結果就是 0 1 2 3 4 5 7 9 這個比較簡單,直接上 先搭建測試環境 typedef struct linklist linklist 構建兩個有序鍊錶 vo...
資料結構考研筆記 線性表
1.線性表的定義 線性表是具有相同特性元素的乙個有限序列。所含元素個數 線性表長度。2.線性表的邏輯特性 只有乙個表頭元素,乙個表尾元素,表頭元素沒有前驅,表尾元素沒有後繼,其他元素只有乙個直接前驅,乙個直接後繼。3.線性表的儲存結構 1 順序儲存結構 順序表 隨機訪問特性 需占用連續的儲存空間 做...