在鍊錶中使用頭結點與尾指標

2021-06-06 13:01:43 字數 2650 閱讀 2711

頭結點

首先,不要被以下三個片語弄混了

煉表頭:資料內容為第乙個元素的結點。

頭指標:指向頭結點元素的指標。

頭結點:資料內容無效,其指標是頭指標。

一句話描述為:頭指標是指向頭結點的指標,頭結點是指向煉表頭的結點。

對於乙個鍊錶來說,頭指標是一定存在的,是訪問鍊錶的入口,如果沒有頭指標則無法對其進行訪問;煉表頭對於非空表來說是一定存在的,非空表則不存在。

注意到,如果說我們不引入頭結點的話,將出現操作不統一的問題:

1、對於元素訪問的或者結點的引用不統一。假設phead是頭指標,pnode是指向其他鍊錶結點的指標。此時頭指標指向煉表頭。

phead->element; //對於煉表頭的訪問

pnode->next->element; //對於其他結點的訪問

2、對於空表與非空表的判定操作不統一。假設phead是頭指標,pnode是指向其他鍊錶結點的指標。此時頭指標指向煉表頭。

phead == null; //對於空表的判定

pnode->next == null; //對於非空表是否訪問到末尾的判定

頭結點的引入可以很好地解決這兩個問題。首先來看看帶頭結點的三種鍊錶形式。

單鏈表:

雙鏈表:

迴圈雙鏈表(迴圈單鏈表類同)

訪問形式統一為:

p->next->element; //統一後的元素訪問

p->next == null; //統一後的末尾判定

個人來講,傾向於在鍊錶中引入頭結點。雖然多出了一塊兒儲存空間,但是相對於大鍊錶來說,這個空間是微不足道的。好處是使所有的操作保持一致性**的編寫也更為簡單。

引申:在佇列的資料結構中, 一種實現方法是佇列的頭指標(或者標號)為對頭的前乙個位置。這種方式也可以看作為頭結點的一種擴充套件方式。

2 尾指標

另外一種鍊錶的技巧是使用尾指標。

尾指標是相對於頭指標而言的,形式與頭指標相同,內容只想鍊錶的最後乙個節點。

通常,鍊錶的插入語刪除操作都是在煉表頭或者鍊錶尾進行。如果只儲存乙個頭指標的話,要在鍊錶尾操作時必須先遍歷整個表,增加了時間複雜度,如果能再儲存乙個尾指標,則可以立即找到鍊錶尾,時間複雜度降為o(1)。

在單向迴圈鍊錶中,時常值儲存乙個尾指標,因為尾指標的下乙個節點即是頭結點。這樣便可以方便地在首尾進行操作。

最後,提供乙個帶頭結點和尾指標的單鏈表插入實現參考**。

#include #include #define elementtype int

struct listnode

;typedef struct

list, *plist;

int inserttail( elementtype x, plist l ) //尾部插入元素

newp->element = x;

newp->next = null;

l->tail->next = newp;

l->tail = newp;

if ( l->head->next == null)

return 0;

}int inserthead( elementtype x, plist l ) //頭部插入元素

newp->element = x;

newp->next = l->head->next;

l->head->next = newp;

return 0;}

int main()

if ( (l->head = malloc(sizeof(struct listnode))) == null )

l->head->next = null; //初始化

l->tail = l->head;

inserttail( 10, l );

inserttail( 11, l );

inserttail( 12, l ); //三次尾部插入

inserthead( 13, l );

inserthead( 14, l ); //兩次頭部插入

inserttail( 15, l );

inserttail( 16, l ); //兩次尾部插入

while( l->head->next != null ) //遍歷輸出

puts("");

return 0;

}

執行結果:

jimmy@mypet:~/code/learnc$ make

gcc -wall -g -o test test.c -std=c99

jimmy@mypet:~/code/learnc$ ./test

14 13 10 11 12 15 16

(完)

初學單向鍊錶中的頭結點與頭指標

頭指標 指向第乙個結點的指標稱為頭指標,每次訪問鍊錶時都可以從這個頭指標依次遍歷鍊錶中的每個元素。特點在於 每個鍊錶都必須要有頭指標。頭結點的意義在於訪問鍊錶時提供鍊錶的位置資訊。頭結點 存放指向具有實際意義的第乙個結點的指標變數的結點,資料域可以為空也可存放鍊錶的結點個數。特點 不是必須要有。頭結...

鍊錶的複習 頭插與尾插有頭鍊錶

此文章用於大一c語言的鍊錶複習 這裡就不再上鍊表官方定義了,直接說我對鍊錶的理解。鍊錶相當於記憶體中一系列不連續的位址通過指標相互聯絡在一起,它需要通過結構體來實現,同時引入了節點的概念,即以前我們通過乙個變數來儲存資料,現在在鍊錶中用節點來儲存資料,因為在鍊錶中,乙個資料總伴隨著乙個指向下乙個資料...

在驅動中使用鍊錶

原始出處 在驅動程式的開發中經常需要用到鍊錶,常見的鍊錶有單向鍊錶和雙向鍊錶,我們只介紹雙向鍊錶的使用方法,ddk為我們提供了標準的雙向鍊錶 list entry,但這個鍊錶裡面沒有資料,不能直接使用,我們需要自己定義乙個結構體型別,然後將list entry作為結構體的乙個子域,如下 所示 typ...