由於單鏈表結點中只有乙個指向其後繼的指標,使得單鏈表只能從頭結點依次順序地向後遍歷。訪問後繼結點的時間複雜度為o(1),訪問前驅節點的時間複雜度為o(n)。為了克服單鏈表的上述缺點,引入了雙鏈表,雙鏈表結點中有兩個指標prior和next,分別指向其前驅節點和後繼結點,使得訪問前後結點的時間複雜度都為o(1)。
雙鏈表中的結點型別描述如下:
typedef
struct dnode dnode,
*dlinklist;
初始化雙鏈表:
dlinklist initlist
(dlinklist& l)
頭插法建立鍊錶:
dlinklist dlist_headinsert
(dlinklist& l)
s->prior = l;
l->next = s;
cin >> x;
}return l;
}
尾插法建立鍊錶:
dlinklist dlist_tailinsert
(dlinklist& l)
r->next =
null
;//尾結點置為空
return l;
}
按位插入操作
bool
listinsert
(dlinklist& l,
int i, elemtype e)
dnode* p = l;
dnode* s =
new dnode;
//申請乙個新的結點
int j =0;
while
(j < i -
1&& p-
>next !=
null)if
(p ==
null
)//插入操作
s->data = e;
s->next = p-
>next;
if(p-
>next !=
null
) s-
>prior = p;
p->next = s;
return
true
;}
按位查詢操作:
bool
getelem
(dlinklist l,
int i)
dnode* s =
new dnode;
s = l;
int j =0;
while
(j < i -
1&& s !=
null)if
(s ==
null
) cout << s-
>next-
>data << endl;
return
true
;}
按值查詢操作:
int
locatelem
(dlinklist& l, elemtype e)
}return j;
}
按位刪除操作
bool
listdelete
(dlinklist& l,
int i, elemtype& e)
dnode* s =
new dnode;
dnode* p;
//*p為需要刪除的結點
s = l;
int j =0;
while
(j < i -
1&& s !=
null)if
(s ==
null
)else
//將*p從鏈中斷開
e = p-
>data;
s->next = p-
>next;
if(s-
>next !=
null
)free
(p);
//釋放結點的儲存空間
return
true;}
}
遍歷操作:
bool
printlist
(dlinklist l)
cout << endl;
return
true
;}
判空操作:
bool
empty
(dlinklist l)
return
false
;}
銷毀操作:
與刪除操作有點類似
void
destorylist
(dlinklist& l)
free
(q);
}}
求表長:
int
length
(dlinklist l)
return j;
}
以上是雙鏈表需要用到的基本操作,時間複雜度均為o(n)。 線性表的鏈式表示(單鏈表)
鍊錶的好處在於插入和刪除元素時只需改變指標的指向,減少操作次數。鍊錶的儲存結構可以是順序的 靜態鍊錶 也可以是無序的。缺點是隨機訪問時需要遍歷整個表。本文用無序的儲存結構實現了單鏈表。線性表的鏈式表示 單向鍊錶 lovesunmoonlight include include include inc...
線性表的鏈式表示 迴圈單鏈表(C )
迴圈單鏈表和單鏈表的區別在於,表中的最後乙個結點的指標不是null,而改為指向頭結點,從而整個鍊錶形成乙個環。迴圈單鏈表可以從表中任意乙個結點開始遍歷整個鍊錶。不僅可以設定頭指標,還可設定尾指標,對於表頭與表尾進行操作都只需要o 1 的時間複雜度 迴圈單鏈表中結點型別的描述如下 typedef st...
線性表的鏈式儲存結構 雙鏈表
雙鏈表對於雙鏈表,採用類似於單鏈表的型別定義,其dlinklist型別的定義如下 typedef struct dnode 宣告雙鏈表節點型別 1.建立雙鏈表 建立雙鏈表也有兩種方法。和頭插法建立單鏈表的過程相似,採用頭插法建立雙鏈表的演算法。void createlistf dlinklist l...