簡體   English   中英

刪除單鏈表中的兩個相鄰節點

[英]Deleting two adjacent nodes in singly linked list

我是學生(還是新秀),我有問題。 我必須刪除單鏈列表中總和等於k的一對節點。 例如,如果鏈接列表為13-> 4-> 5-> 4-> 3k = 9 ,則我的函數應將列表轉換為13-> 3 (4 + 5 = 9,5 + 4 = 9 )。 這是我未完成的代碼:

typedef struct _node
{
    int value;
    struct _node* next;
}Node;

void remove(Node **list, int k)
{
    if(*list == NULL || (*list)->next == NULL)
       return;

    Node *prev = *list;
    Node *tmp = (*list)->next;

    while(tmp != NULL)
    {
        if(prev->value + tmp->value == k)
        {
             free(prev);
             prev = tmp->next;
             free(tmp);
             tmp = tmp->next->next;
        }
    }
}

我有一個主意,但我不知道如何在while循環中設置條件。 有人知道如何重寫嗎?

現在,您在第一個匹配項處斷開了鏈接:在您的示例中,刪除4之后,13的next仍然指向該鏈接,因此一個懸空指針也指向該鏈接。 但這不會發生,因為您永遠不會從13移動到任何地方,因為您僅在刪除元素時才向前迭代(這對13-> 4不會發生)。

您應該考慮的第三件事是,您實際上應該標記要刪除的元素,否則您將無法刪除示例中的后四個元素。

首先->您不在列表中前進,因此將導致無限循環。

第二->如果tmp的下一個節點為NULLtmp=tmp->next->next將給您分段錯誤。

第三->當釋放內存時,您也在斷開鏈表,因此在基礎代碼中聲明了pointToPrev指針,該指針將指向prev指針后面的節點,但是如果釋放內存,它將將指向tmp net節點保存列表。

最好將while循環更改為此:

 `  int indicator=0;
    Node *pointToPrev = *list;
    if(prev->value + tmp->value == k)
    {
         *list=temp->next;
         free(tmp);
         free(prev);
         indicator=2;
    }
    while((tmp != NULL)&&(indicator!=2))
    {
          if(prev->value + tmp->value == k)
          {
             free(prev);
             pointToPrev->next = tmp->next;
             free(tmp)
             break; //AS YOU DON'T NEED TO COMPLETE THE ENTIRE WHILE LOOP AS SUM HAS BEEN ALREADY FOUND
          }
          else //THIS WILL SAVE YOU FROM THE INFINITE LOOP 
          {   
             tmp = tmp->next;
             prev = prev->next;
             if(indicator==0)
             {
                  pointToPrev = *list;
                  indicator=1;
             }
             else
                  pointToPrev=pointToPrev->next;
          }
    }

由於存在兩個重疊條件來控制是否應刪除給定節點,因此此問題變得很復雜:如果其值與前一個節點的值之和是目標值,或者其值與下一個節點的值之和是目標值。 而且,除了當它是最后一個節點之外,您始終將下一個節點與下一個節點進行比較,因此您必須紀念它所攜帶的值,否則必須避免將其刪除。

可以通過從第二個節點開始的普通鏈表遍歷來解決此問題(或者如果少於兩個節點,則無需執行任何操作)。 每次迭代

  • 確定當前節點和先前節點的節點值之和是否等於目標值
  • 如果是這樣, 或者在上一個循環迭代中該評估為真,則刪除上一個節點

循環終止后,請根據需要刪除最后一個節點。 您需要在每次迭代之間攜帶足夠的狀態,以適當地執行刪除操作,並記住上一次迭代中求和評估的結果,但是總的來說,這並不比按值刪除單個節點困難得多。

這種方法非常簡單,因為它將每次評估中必須考慮的案例數限制為兩個,它永遠不需要在列表中比下一個節點更向前看,並且在刪除一個節點時,該節點始終具有與當前節點的關系相同。 該代碼應保留為應做的練習。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM