一、雙鏈表
單鏈表有乙個大問題就是訪問後繼結點比較方便,但是如果訪問前驅結點,就需要從頭開始來一遍,時間複雜度為o(n),這就很讓人不爽了,所以就有了雙鏈表。
顧名思義,雙鏈表就是結點中有兩個指標prior和next,分別指向其前驅結點和後繼結點。如下圖所示:
雙鏈表中結點型別的描述如下:
typedef struct dnodednode, *dlinklist;
雙鏈表的特點就是比單鏈表多了乙個*prior,所以在實現基本操作的過程中要記得修改*prior,保證不斷鏈。
下面以雙鏈表的插入和刪除操作為例。
1.雙鏈表的插入操作
在雙鏈表中p所指的結點之後插入結點*s,其過程如下圖所示:
插入操作的**片段如下:
①s->next=p->next; //將結點*s插入到結點*p之後
②p->next->prior=s;
③s->prior=p;
④p->next=s;
2.雙鏈表的刪除操作刪除雙鏈表中結點*p的後繼結點*q,其指標變化如下圖所示
刪除操作的**片段如下:
p->next=q->next; //操作步驟1
q->next->prior=p; //操作步驟2
free(q); //釋放結點空間
二、迴圈鍊錶1.迴圈單鏈表這個字尾也帶個單鏈表,但是與單鏈表不同的是表中最後乙個結點不是null,而是指向頭結點,這就形成乙個迴圈,是不是很神奇…
示意圖如上,表尾結點*r的next指向l,所以判空和遍歷的終止條件就要相應的進行修改。插入、刪除操作和單鏈表基本一樣,除了對於隊尾結點的操作需要特殊一點,因為要保持迴圈的特性。
單鏈表只能從表頭結點開始往後順序遍歷整個鍊錶,而迴圈單鏈表可以從表中任意乙個結點開始遍歷整個鍊錶(個人感覺作用不是很大,平時沒接觸過…如果有大佬接觸了歡迎交流)。
2.迴圈雙鏈表
迴圈雙鏈表就是頭結點的prior指標還要指向表尾結點,示意圖如下:
看這個圖有種莫名的舒適感…
三、靜態鍊錶
靜態鍊錶借助陣列來描述線性表的鏈式儲存結構,結點也有資料域data和指標域next,這裡的指標時結點的相對位址(陣列下標),又稱游標。和順序表一樣,靜態鍊錶也要預先分配一塊連續的記憶體空間。
靜態鍊錶和單鏈表的對應關係如下圖:
靜態鍊錶結構型別的描述如下:
#define maxsize 50 //靜態鍊錶的最大長度
typedef structslinklist[maxsize];
靜態鍊錶以next==-1作為結束標誌,其插入、刪除與動態鍊錶一樣,修改指標即可。但是吧,這個東西用起來沒有單鏈表方便,據說在一些不支援指標的高階語言中很好用,例如basic(沒試過)。 雙鏈表 迴圈鍊錶
一 雙鏈表 對於雙鏈表,採用類似於單鏈表的型別定義,其dlinklist型別的定義如下 typedef struct dnode 宣告雙鏈表節點型別 dlinklist 1.建立雙聯表 1 頭插法 void createlistf dlinklist l,elemtype a,int n 頭插法建立...
迴圈鍊錶和雙鏈表
1 假設在長度大於1的單迴圈鍊錶中,既無頭結點也無頭指標。s為指向某個結點的指標,試編寫演算法刪除結點 s的直接前驅結點。2 已知由單鏈表表示的線性表中,含有三類字元的資料元素 如 字母 數字和其它字元 設計演算法構造三個以迴圈鏈表示的線性表,使每乙個表中只含同一類的字元,且利用原表中的結點空間作為...
迴圈鍊錶 迴圈雙鏈表 迴圈單鏈表
迴圈單 雙鏈表,建立 初始化 尾插 頭插 遍歷 插入 刪除 判空 部分函式採用過載 此處為c include include include using namespace std typedef struct lnodelnode,linklist typedef struct dnodednod...