在O(1)的時間內刪除鏈表的指定結點
題目:給定單項鍊表的頭指針和一個結點指針,定義一個函數在o(1)的時間刪除該結點,鏈表的定義如下:
struct ListNode{
int value;
ListNode* next;
};
函數定義:void DeleteNode(ListNode** PListHead,ListNode* pToBedelete);
如上圖所示,想要刪除一個單鏈表的中的某個結點有兩種方式:
1、如上圖中的( b)所示:要刪除i結點,必須從頭掃描,掃到h(i的前一個結點),然後讓其next值指向j(i的下一個位置),然後就可以刪除i了。此方法的複雜度爲O(n),因爲要刪除某個結點必須找到其上一個結點,故需要從頭遍歷。
2、如上圖中的(c)所示:要刪除i結點,可以先把i的下一節點的值賦給i結點,然後讓i的next值指向下一節點的下一結點,就相當於刪除i結點。(注意要保存i->next的這個結點,然後再刪除),此算法複雜度爲O(1),但是必須要求此要刪除結點一定是鏈表中的結點,且當要刪除的結點爲最後一個結點時,必須用第一種方法,順序遍歷後找到最後一結點的上一結點,然後刪除,但此方法的平均時間複雜度仍然爲O(1).
故代碼如下:
注意:delete結點後一定要讓結點指向nullptr(每次都忘。。。)
1 //在O(1)的時間刪除鏈表指定的結點 2 struct ListNode{ 3 int value; 4 ListNode *next; 5 }; 6 void DeleteNode(ListNode** pListHead, ListNode *pToBeDelete) 7 { 8 if (pListHead == nullptr || *pListHead == nullptr || pToBeDelete == nullptr) 9 return; 10 if (*pListHead == pToBeDelete&&pToBeDelete->next == nullptr)//若是頭節點也是最後一個節點 11 { 12 delete pToBeDelete; 13 pToBeDelete = nullptr; 14 *pListHead = nullptr; 15 } 16 else if (*pListHead != pToBeDelete&&pToBeDelete->next == nullptr)//若是最後一個節點 17 { 18 ListNode* p = *pListHead; 19 while (p->next!=pToBeDelete) 20 { 21 p = p->next; 22 } 23 delete pToBeDelete; 24 pToBeDelete = nullptr; 25 p->next = nullptr; 26 } 27 else{//要刪除的節點不是尾節點 28 ListNode* pd = pToBeDelete->next; 29 pToBeDelete->value = pd->value; 30 pToBeDelete->next = pd->next; 31 delete pd; 32 pd = nullptr; 33 } 34 }