1. 程式人生 > >連結串列、頭指標、頭結點【轉】

連結串列、頭指標、頭結點【轉】

圖1為線性表(ZHAO, QIAN, SUN, LI, ZHOU, WU, ZHENG, WANG)的邏輯狀態。頭指標 指示連結串列中第一個結點(即第一個資料元素的儲存映像)的儲存位置。同時,由於最後一個數據元素沒有直接後繼,則線性連結串列中最後一個結點的指標為“空”(NULL)。

圖2.6

圖1 線性連結串列的邏輯狀態

由上述描述可見,單鏈表可由頭指標來唯一確定,在C語言中可用“結構指標”來描述。

  1. //-----線性表的單鏈表儲存結構-----  
  2. typedef struct LNode{  
  3.     ElemType   data;  
  4.     struct LNode  *next;  
  5. }LNode, *LinkList;  

有時在單鏈表的第一個結點之前附設一個結點,稱之為頭結點  頭結點的資料域可以不儲存任何資訊,也可以儲存如線性表長度等類的附加資訊,頭結點的指標域儲存指向第一個結點的指標(即第一個元素結點的儲存位置)。如圖2(a)所示,此時,單鏈表的頭指標指向頭結點。若線性表為空,則頭結點的指標域為“空”,如圖2(b)所示。

圖2.7圖2 帶頭結點的單鏈表   (a)非空表;(b)空表

    迴圈連結串列 是另一種形式的鏈式儲存結構。它的特點是表中最後一個節點的指標域指向頭結點,整個連結串列形成一個環。由此,從表中任一結點出發均可找到表中其他結點,如圖3所示為單鏈的迴圈連結串列 。

圖2.12 圖3 單鏈迴圈表 (a)非空表;(b)空表

迴圈連結串列的操作和線性連結串列基本一致,差別僅在於演算法中的迴圈條件不是p或p->next 是否為空,而是它們是否等於頭指標,但有的時候,若在迴圈連結串列中設立尾指標而不設頭指標(如圖4(a)所示),可使某些操作簡化。例如將兩個線性表合併成一個表時,僅需將一個表的尾表和另一個表的頭表相接。當線性表以圖2.4(a)的迴圈連結串列作儲存結構時,這個操作僅需改變兩個指標值即可,運算時間為O (1)。合併後的表如圖4(b)所示。

圖2.13圖4 僅設尾指標的迴圈連結串列 (a)兩個連結串列;(b)合併後的表

     以上討論的鏈式儲存結構的節點中只有一個指示直接後繼的指標域,由此,從某個結點出發只能順指標往後尋查其他結點。若要尋查節點的直接前趨,則需從表頭指標出發。換句話說,在單鏈表中,NextElem的執行時間為O(1),而PriorElem的執行時間為O(n)。為克服單鏈表這種單向性的缺點,可利用雙向連結串列

 。顧名思義,在雙向連結串列的結點中有兩個指標域,其一指向直接後繼,另一指向直接前趨。在C語言中可描述如下:

  1. //-----線性表的雙向連結串列儲存結構-----  
  2. typedef struct DuLNode{  
  3.     ElemType   data;  
  4.     struct DuLNode  *prior;  
  5.     struct DuLNode  *next;  
  6. }DuLNode, *DuLinkList;  

和單鏈的迴圈表類似,雙向連結串列也可以有迴圈表,如圖5(c)所示,連結串列中存有兩個環,圖5(b)所示為只有一個表頭結點的空表。在雙向連結串列中,若d為指向表中某一個結點的指標(即d為DuLinkList型變數),則顯然有

d->next->prior=d->prior->next=d

圖2.14

圖5 雙向連結串列示例 (a)結點結構;(b)空的雙向迴圈連結串列;(c)非空的雙向迴圈連結串列