1
頭結點
首先,不要被以下三個片語弄混了
煉表頭:資料內容為第乙個元素的結點。
頭指標:指向頭結點元素的指標。
頭結點:資料內容無效,其指標是頭指標。
一句話描述為:頭指標是指向頭結點的指標,頭結點是指向煉表頭的結點。
對於乙個鍊錶來說,頭指標是一定存在的,是訪問鍊錶的入口,如果沒有頭指標則無法對其進行訪問;煉表頭對於非空表來說是一定存在的,非空表則不存在。
注意到,如果說我們不引入頭結點的話,將出現操作不統一的問題:
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...