帶哨兵節點和不帶哨兵節點的單鏈表操作的對比

2021-09-07 12:26:50 字數 2484 閱讀 7905

哨兵節點:哨兵節點(sentinel)是乙個啞元節點(dummy node),可以簡化邊界條件。是乙個附加的鍊錶節點,該節點作為第乙個節點,它的值域中並不儲存任何東西,只是為了操作的方便而引入的。如果乙個鍊錶有哨兵節點的話,那麼線性表的第乙個元素應該是鍊錶的第二個節點。 

很多情況下,需要處理當前節點的前驅節點,如果是沒有哨兵節點的鍊錶,對第乙個節點,即頭節點,沒有前驅節點。如果不作特殊處理,就可能出錯;如果對它特別對待,就會增加**複雜性,還會降低程式效率。而如果有哨兵節點的話, 線性表的每個位置的節點都有前驅節點,因此可以統一處理。 

當鍊表為空時,沒有哨兵節點的鍊錶的頭節點為null,處理起來也和其他情況不同。帶哨兵節點的鍊錶,當其為乙個空煉表時,僅含哨兵節點,哨兵節點的指標域為空,和其他情況的表尾是一樣的。

定義鍊錶的節點:

typedef struct

_nodenode, *pnode;

定義鍊錶結構體的資料型別。

建立乙個鍊錶。

沒有哨兵節點的情況:

pnode createlist(void

)else

scanf("%d

", &input);

}return

head;

}

有哨兵節點的情況:

pnode createlistwithsentinel(void

)

return

head;

}

沒有哨兵節點時,新增乙個節點要先判斷是否是第乙個節點,並單獨保留第乙個節點的指標,以便於返回整個鍊錶的頭指標。有哨兵節點時,煉表頭是固定的,不可能為空,後續的節點都是鏈結在前乙個節點的,不需要單獨判斷是否為頭節點。

遍歷輸出鍊錶。

沒有哨兵節點:

void printlist(const

pnode head)

printf("\n

");}

有哨兵節點:

void printlistwithsentinel(const

pnode head)

printf("\n

");}

差別不大。

在指定的位置前插入乙個節點。第乙個位置為0 

沒有哨兵節點:

pnode insertnoden(pnode head, int pos, int

value)

for(count = 1; count < pos && prev->next != null; count++)

temp->next = prev->next;

prev->next = temp; //

鏈return

head;

}

有哨兵節點:

void insertnodewithsentineln(const pnode head, int pos, int

value)

temp->next = prev->next;

prev->next = temp; //

鏈}

有哨兵節點時,不需要判斷鍊錶為空和插入點在第乙個位置節點的情況。

刪除指定位置的節點。

沒有哨兵節點:

pnode deletenoden(pnode head, int

pos)

/*刪除第乙個節點,即刪除的是頭節點的情況

*/if(pos == 0

)

for(count = 1; count < pos && prev->next != null; count++)

temp = prev->next;

if(temp !=null)

free

(temp);

return

head;

}

有哨兵節點:

void deletenodewithsentineln(const pnode head, int

pos)

temp = prev->next;

if(temp !=null)

free

(temp);

}

有哨兵節點時,不需要判斷鍊錶為空和刪除第乙個位置節點的情況。

總結:

帶哨兵節點的鍊錶,需要額外的乙個節點,但插入和刪除等操作不需要額外的判斷;不帶哨兵節點,在處理鍊錶為空時,和其他情況不一樣,需要單獨判斷一次。 

帶哨兵節點的鍊錶,插入或刪除時,不論操作的位置,表頭都不變,不需要額外的判斷;不帶哨兵節點的鍊錶,插入或刪除操作發生在第乙個節點時,表頭指標都要變化,需要額外的處理。

鍊錶中的哨兵節點

哨兵節點 在沒有哨兵節點時 對鍊錶進行插入操作時,需要判斷當前鍊錶是否有節點,大致如下 if head null else在進行刪除操作時,需要判斷刪除的是否是最後乙個節點,大致如下 if head.next null else有哨兵節點時 對鍊錶進行插入操作時,需要判斷當前鍊錶是否有節點,大致如下...

演算法 資料結構 鍊錶和哨兵節點

鍊錶是一種基礎的資料結構,但對於一些初學者來說,實現乙個鍊錶還是比較困難的,許多操作作用在頭部或尾部時需要特殊處理。比如下面這段 template typename t void linkedlist remove linkedlistnode node 上述 進行了兩次的空值判斷,有可能會更新煉表...

實驗2 不帶頭節點的單鏈表

編寫函式slnklist delx linklist head,datatype x 刪除不帶頭結點單鏈表head中第乙個值為x 的結點。並構造測試用例進行測試。include slnklist.h 請將本函式補充完整,並進行測試 linklist delx linklist head,dataty...