資料結構考研 2 線性表

2021-10-03 18:05:37 字數 4870 閱讀 4968

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 雙鏈表

雙鏈表節點中有兩個指標priornext分別指向前驅節點和後繼節點

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 順序儲存結構 順序表 隨機訪問特性 需占用連續的儲存空間 做...