1 3 線性表的鏈式儲存結構

2021-08-20 10:38:36 字數 3443 閱讀 5404

一、單鏈表:以元素 + 指標(指示後繼元素位置) = 結點(表示資料元素)

以線性表中的第乙個資料元素a1的儲存位址作為線性表的位址,稱作線性表的頭指標。

為了操作方便,在第乙個結點之前虛加乙個「頭結點」,以指向結點的指標為鍊錶的頭指標。

二、結點和單鏈表的c語言描述

adt(abstract data type):抽象資料型別

typedef struct lnodelnode, *linklist;

注:理解:typedef (struct lnode*) (linklist)

linklist l; //l為單鏈表的頭指標。

三、單鏈表操作的實現

getelem(l, i, &e)      //取第i個資料元素

listinsert(&l, i, e)  //插入資料元素

listdelete(&l, i, e)  //刪除資料元素

clearlist(&l)         //重新置為乙個空表

createlist(&l, n)     //生成含n個資料元素的鍊錶

線性表的操作:

getelem(l, i, &e)在單鏈表中的實現:

單鏈表是一種順序訪問的結構,為找第i個資料元素,必須先找到第i - 1個資料元素。

因此,查詢第i個資料元素的基本操作為:移動指標,比較j(計數器)和i。

令指標p始終指向線性表中第j個資料元素。

status getelem_l(linklist l, int i, elemtype &e)

if(!p || j > i)

return error;    //元素不存在 or i值不合理

e = p -> data;           //取得第i個元素

return ok;

}//getelem_l

時間複雜度:o(n)--> o(listlength(l))

線性表的操作:

listinsert(&l, i, e)在單鏈表中的實現:

在鍊錶中插入結點只需要修改指標。

但同時,若要在第i個結點之前插入元素,修改的是第i - 1個結點之前的指標。

因此,在單鏈表中第i個結點之前進行插入的基本操作為:

找到線性表中第i - 1個結點,然後修改其指向後繼的指標。

status listinsert_l(linklist &l, int i, elemtype e)

if(!p || j > i - 1)       //......

return error;

s = new lnode;

//生成新節點

if(s == null)

return error;

s -> data = e;            //插入         

s -> next = p -> next;

p -> next = s;

return ok;

}演算法的時間複雜度:o(listlength(l)) --> 這裡的複雜度與順序表的插入複雜度o(n)是有區別的!!!

主要體現在查詢方面 --> 具體操作方面 o(1)

前插結點:設p指向鍊錶中某結點,s指向待插入的為x的新結點,將*s插入到*p的前面。

(第一種方法)與後插不同的是:首先要找到*p的前驅*q(...),然後再完成在*q之後

插入*s, 設單鏈表頭指標為l。

操作如下:

1. q = l;

while( q -> next != p)  //找到*p的直接前驅

q = q -> next;

s -> next = q -> next;

q -> next = s;

時間複雜度:o(n)

(第二種方法)前插操作需要找*p的前驅。(上乙個方法)可以將*s插入到*p的後面(後插)

2. s -> next = p -> next;

p -> next = s;

然後再交換資料域即可;

p -> data = s -> data;

時間複雜度:o(1)

線性表的操作:

listdelete(&l, i, &e)在單鏈表中的實現:

基本操作:

找到線性表中第i - 1個結點,修改其指向後繼的指標。

q = p -> next;

p -> next = q -> next;

e = q -> data;

delete(q);

也可以:

p -> next = p -> next -> next;

dalete(...)// 可見這種方法的弊端了吧

status listdelete_l(linklist &l, int i, elemtype &e)

//......

if(!(p -> next) || j > i - 1)

return error;

//刪除並釋放結點

q = p -> next; 

p -> next = q -> next;

e = q -> data;

delete(q);

return ok;

}//listdelete_l

時間複雜度:o(n)

線性表的操作:

clearlist(&l)在單鏈表中的實現:

void clearlist(&l)

}時間複雜度:o(n)

頭插法:逆位序輸入n個資料元素的值,建立帶頭結點的單鏈表。

例: 輸入 1, 2, 3, 4, 5

得到 5, 4, 3, 2, 1

操作步驟:

一、建立乙個"空表";

二、輸入資料元素an, 建立結點並插入;

三、輸入資料元素a(n -1), 建立結點並插入;

四、依次類推,直到a1;

void createlist_l(linklist &l, int n) 

}時間複雜度:o(n)

尾插法:.....(向對於頭插法)。

(老頭子們的)定義:正序輸入n個資料元素的值。

建立不帶頭結點的單鏈表尾插法:

linklist create_linklist2()

if(r != null)                  //非空表最後結點的指標域為空

r -> next = null;

return l;

}建立帶頭結點的單鏈表尾插法:

linklist create_linklist2()

r -> next = null;

return l;

}頭結點的兩個優點:

a、由於開始結點的位置被存放在頭結點的指標域中,所以在鍊錶的第乙個位置上的操作

就和在表中的其他位置上的操作一致,無需進行特殊處理;

b、無論鍊錶是否為空,其頭指標是指向頭結點的非空指標(空表中頭結點的指標域為空)

因此空表和非空表的處理就統一了唄。

線性表的鏈式儲存結構

線性表的鏈式儲存結構 順序儲存結構不足的解決辦法 缺點 最大的缺點就是插入和刪除時需要移動大量元素。為了表示每個資料元素 ai與其直接後續資料元素 ai 1 之間的邏輯關係,對資料元素 ai來說,除了儲存其本身的資訊之外,還需儲存乙個指示其直接後續的資訊。我們把儲存資料元素資訊的域稱為資料域,把儲存...

線性表的鏈式儲存結構

線性表的鏈式儲存結構,雙向鍊錶實現 package 線性表 public class dulinklist public node t data,node prev,node next 儲存該鍊錶的頭節點 private node header 儲存該鍊錶的尾節點 private node tail...

線性表的鏈式儲存結構

順序儲存結構的缺點 插入和刪除時需要移動大量元素 鏈式儲存結構的特點 用一組任意的儲存單元儲存線性表的資料元素 資料結構 儲存分配方式 時間效能 空間效能 順序儲存結構 用一段連續的儲存單元一次儲存線性表的資料元素 查詢 o 1 插入刪除 o n 需要預分配儲存空間,分大了浪費,分小了易發生上溢 單...