
思路一:不存在哨兵頭結點時
該題為鏈表中資料的洗掉,即將符合條件的節點釋放掉,將剩余節點重新連接起來,因為不只是將需要洗掉的節點釋放掉,而且要將該節點的前后兩個節點連接起來,因此不能單純地找該節點,同時應該找前一個節點,按照以前的思路,定義一個指標pre,在cur依次向后判斷的時候,跟隨充當目標節點的前一個節點

這樣依次向后排查,直到cur指向空指標停止
但是忽略了一個問題,萬一第一個節點就需要洗掉

如圖,若是第一個節點就需要洗掉,則將cur釋放之后,在pre與next連接的程序中,因為pre此時是空指標,無法將next儲存到pre當中去,此時就要另外考慮思路
當第一個節點需要洗掉,可以在該節點洗掉后把后一個節點當作頭節點,再依次進行篩選
struct ListNode* removeElements(struct ListNode* head, int val){
struct ListNode* pre=NULL;
struct ListNode* cur=head;
while(cur!=NULL)
{
struct ListNode* next=cur->next;
if(cur->val==val)
{
if(pre==NULL)//當第一個節點需要洗掉,改變頭節點
{
free(cur);
head=next;
cur=next;
}
else
{
pre->next=next;
free(cur);
cur=next;
}
}
else
{
pre=cur;
cur=cur->next;
}//如果不需要洗掉,則依次向后排查
}
return head;
}
注意:
1.因為最后要再次回傳頭節點,在頭節點需要洗掉的這種情況下,記得把下一個節點傳到head中
2.在利用指標的時候要注意函式的回傳值型別,當函式是void型別的時候,對傳進來的地址要進行改變,則需要二級指標,否則就是單純的值傳遞,函式外無法改變,如果像本題要回傳一個地址,這不需要二級指標
3.洗掉一個節點不是單純地將前后兩個節點連起來,要將該節點釋放掉,然后指標cur指向下一個節點
思路二:含有哨兵頭節點
因為要考慮第一個節點是否洗掉的問題,其實我們可以自己定義一個哨兵頭節點,相當于鏈表加了一個首相,原先的頭節點就變成了第二個,因此只需要依次向后排查即可

struct ListNode* removeElements(struct ListNode* head, int val){
struct ListNode* guardhead=(struct ListNode*)malloc(sizeof(struct ListNode));
guardhead->next=head;
struct ListNode* pre=NULL;
struct ListNode* cur=guardhead;
while(cur!=NULL)
{
struct ListNode* next=cur->next;
if(cur->val==val)
{
pre->next=next;
free(cur);
cur=next;
}
else
{
pre=cur;
cur=cur->next;
}
}
head=guardhead->next;
free(guardhead);
return head;
}
注意:
1.因為guardhead是新開辟出來的,最后回傳的時候不能單純地回傳guardhead->next,否則會出現記憶體泄露的問題,最后要把guardhead釋放掉
2.到最后連表示已經洗掉完了的,因此直接將guardhead->next賦給head即可
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/274757.html
標籤:其他
上一篇:Fdog系列(一):思來想去,不如寫一個聊天軟體,那就從仿QQ注冊頁面開始吧。
下一篇:個人微信小程式上線還要付費?!
