下面我們講下具體帶頭結點和不帶頭結點的一個情況。
頭指針:通常使用“頭指針”來標識一個鏈表,如單鏈表L,頭指針為NULL的時表示一個空鏈表。鏈表非空時,頭指針指向的是第一個結點的存儲位置。
頭結點:在單鏈表的第一個結點之前附加一個結點,稱為頭結點。頭結點的Data域可以不設任何信息,也可以記錄表長等相關信息。若鏈表是帶有頭結點的,則頭指針指向頭結點的存儲位置。
無論是否有頭結點,頭指針始終指向鏈表的第一個結點。如果有頭結點,頭指針就指向頭結點(只不過頭結點的數據域為
第一點:
不帶頭節點: p1->p2->p3 ->p1->p2->p3-> p1…
我們先創建頭指針,初始化的時候只需要將頭指針賦NULL就可以了;大家想想,如果在這種情況下,我們進行頭刪操作,最后一步必須得做的事就是: 更新頭指針的指向。
或者換句話說,一旦對首元節點(頭指針指向首元結點)進行操作,首尾工作必定得進行更新。
帶頭節點:head-> p1->p2->p3 ->p1->p2->p3-> p1…
與上邊相反,每次進行涉及到首元結點的操作后,更新的過程就會很簡單。我們不需要再去移動頭指針,只需要固定的更新頭結點中的指針域就可以了。
第二點:
再者,帶頭節點可以方便,快速的定位鏈表第1個節點。
比如循環鏈表的時候,刪除p1 的時候:
head->next = p2;
p3->next = head->next;
free(p1);
思路很清晰,鏈表開始的第1個節點現在就是head->next 即 p2
否則沒有頭節點:
p3->next = p1->next;
free(p1);
會不會有一種鏈表第1個節點到底是哪個的感覺?
第三點:
不帶頭結點的單鏈表對於第一個節點的操作與其他節點不一樣,需要特殊處理,這增加了程序的復雜性和出現bug的機會,因此,通常在單鏈表的開始結點之前附設一個頭結點