線性表(三)——線性連結串列(單鏈表)
阿新 • • 發佈:2018-12-03
線性連結串列(單鏈表)
構造原理
用一組地址任意的儲存單元(連續的或不連續的)依次儲存表中各個資料元素, 資料元素之間的邏輯關係通過指標間接地反映出來。
線性表的這種儲存結構稱為線性連結串列,又稱為單鏈表。
在C語言中線性連結串列的定義如下:
typedef struct node { ElemType data; struct node *link; }LNode, *LinkList; //定義一個線性連結串列型別 //上述程式碼相當於給結構體 node 定義了一個別名LNode和一個指標別名LinkList LinkList list; //宣告一個線性連結串列List,List為整個線性連結串列的頭指標 //等價於 struct node *list; 等價於 LNode *list;
基本操作
1、求線性連結串列的長度
1、非遞迴演算法:
int LENGTH( LinkList list ){
LinkList p=list;
int n=0; /* 連結串列的長度置初值0*/
while(p!=NULL){
p=p->link;
n++;
}
return n; /* 返回連結串列的長度n */
}
此演算法的時間複雜度O(n)
2、遞迴演算法:
int LENGTH(LinkList list){ if(list != NULL) return 1+LENGTH( list->link); else return 0; }
連結串列本身就是一種遞迴結構,但遞迴演算法時間效率往往比非遞迴低。
2、建立一個線性連結串列
從頭到尾建立連結串列
LinkList CREATE( int n ){ LinkList p, r, list=NULL; datatype a; for(i=1;i<=n;i++){ READ(a); /* 取一個數據元素*/ p=(LinkList)malloc(sizeof(LNode)); //申請一個新的鏈結點 需要引入alloc.h p->data=a; p->link=NULL; if (list==NULL) list=p; else r->link=p; /* 將新結點連結在連結串列尾部*/ r=p; //指標變數r總是指向連結串列末尾 } return list; }
該演算法的時間複雜度O(n)
3、在非空線性連結串列的第一個結點前插入一個數據信息為item 的新結點
void INSERTLINK1( LinkList &list, ElemType item ){
//list存放連結串列的首地址
LinkList p;
p=(LinkList)malloc(sizeof(LNode));
p->data=item; /* 將item送新結點資料域*/
p->link=list; /* 將list送新結點指標域*/
list=p; /* 修改指標list的指向*/
}
該演算法的時間複雜度為O(1),與連結串列長度n無關
4、線上性連結串列中由指標q 指的鏈結點之後插入一個數據信息為item 的鏈結點
void INSERTLINK2( LinkList &list, LinkList q,ElemType item ){
LinkList p;
p=(LinkList)malloc(sizeof(LNode));
p->data=item; /* 將item送新結點資料域*/
if (list==NULL) { /* 若原連結串列為空*/
list=p;
p->link=NULL;
}else{ /* 若原連結串列為非空*/
p->link=q->link;
q->link=p;
}
}
該演算法的時間複雜度為O(1),與連結串列長度n無關
4、從非空線性連結串列中刪除q指的鏈結點,設q的直接前驅結點由r指出
void DELETELINK1( LinkList &list, LinkList r, LinkList q ){
if (q==list)
list=q->link; /* 刪除連結串列的第一個鏈結點*/
else
r->link=q->link; /* 刪除q指的鏈結點*/
free(q); /* 釋放被刪除的結點空間*/
}
該演算法的時間複雜度為O(1),與連結串列長度n無關
5、從非空線性連結串列中刪除q指的鏈結點,不知q的直接前驅節點
比4增加了一個尋找q直接前驅節點r的過程
void DELETELINK2( LinkList &list, LinkList q ){
LinkList r;
if (q==list) { /*當刪除連結串列第一個結點*/
list=list->link;
free(q); /*釋放被刪除結點的空間*/
}else {
r=list; //尋找q的直接前驅節點r
while( r->link!=q &&r->link!=NULL)
r=r->link; /*移向下一個鏈結點*/
if (r->link!=NULL){
r->link=q->link;
free(q);
}
}
}
該演算法的時間複雜度為O(n)
線性錶鏈式儲存結構的特點
1、優點
(1)儲存空間動態分配,可以根據實際需要使用。
(2)不需要地址連續的儲存空間。
(3)插入/刪除操作只須通過修改指標實現,不必移動資料元素,操作的時間效率較高。(無論位於連結串列何處,無論連結串列的長度如何,插入和刪除操作的時間都是Ο(1))
2、缺點
(1)每個鏈結點需要設定指標域(儲存密度小)。
(2)是一種非隨機儲存結構,查詢、定位等操作要通過順序掃描連結串列實現,時間效率較低。(時間為Ο(n))