【问题标题】:Remove duplicate elements from a sorted linked list从排序的链表中删除重复元素
【发布时间】:2013-04-28 19:25:37
【问题描述】:

我正在尝试使用 C 程序从排序链表中删除重复项,并且我正在使用从起始节点遍历列表的简单概念。遍历时,将每个节点与其下一个节点进行比较。如果下一个节点的数据与当前节点相同,则删除下一个节点。

我的代码是:

struct node *remove_dup(struct node *start)
{
    struct node *p,*tmp;
    p=start;
    while(p!=NULL)
    {
        if(p->info==p->link->info)
        {
          tmp=p->link;  
          p->link=p->link->link;
          free(tmp);
        }
        p=p->link;
    }
    return start;
}

它没有给我正确的答案!我的执行有什么问题?我的概念错了吗?

【问题讨论】:

  • 什么是输入不产生正确结果的例子?
  • p = p->link; 语句需要进入else 分支。
  • 您遇到任何错误吗?
  • 是的,我意识到列表是排序的,在发布之后。因此删除了我的评论:)
  • 逐行遍历代码,每一行之后,查看链表。在某些时候,列表将不正确。这就是错误所在。

标签: c algorithm singly-linked-list


【解决方案1】:

由于您的代码检查下一个元素,因此您需要在前一个元素处停止,如下所示:

while (p != NULL && p->link != NULL) {
    ...
}

拥有条件的第一部分的唯一原因是捕获空列表。

此外,您不应该在删除元素时使指针前进。否则,您将无法正确处理超过两个元素的运行。

【讨论】:

    【解决方案2】:
    struct node *remove_dup(struct node *start)
    {
        struct node *p,*next;
    
        for(p=start; p; p = next) {
            next = p->link; 
            if( !next || p->info != next->info) continue;
            p->link = next->link;
            free(next);
            next = p;
        }
        return start;
    }
    

    或等价的(不搞乱下一个)

    struct node *remove_dup(struct node *start)
    {
        struct node *p;
    
        for(p=start; p; ) {
            struct node *next = p->link; 
            if( !next || p->info != next->info) { p = next; continue; }
            p->link = next->link;
            free(next);
        }
        return start;
    }
    

    【讨论】:

    • 在 for 循环中包含 p = p->link 不是更好吗? (我的意思是里面 ---- for (; ; p=p->link))
    • 不,因为您不想在删除后前进。
    • 但这正是你在循环的第一行所做的事情?
    • 但是next 的值在循环的最后一行被(有条件地)重置为 p。
    • 你不能只在当前的实现中这样做,我同意。
    【解决方案3】:

    我在 Java 中的回答:

    public void removeDuplicate() {
        if (first == null) {
            throw new NoSuchElementException("The linkedlist contains no nodes.");
        }
        Node temp = first;
        while (temp != null && temp.next != null) {
            if (temp.element == temp.next.element) {
                temp.next = temp.next.next;
            } else {
                temp = temp.next;
            }
        }
    }
    

    【讨论】:

      【解决方案4】:
      void removeDuplicate()
      {
          if(head == NULL)
              return;
          Node<T>* pPre = head;
          Node<T>* pCur = pPre->pNext;
          while (pCur != NULL)
          {
              if(pCur->elemet == pPre->elemet)
              {
                  pPre->pNext = pCur->pNext;
                  pCur = pPre->pNext;
              }
              else
              {
                  pPre = pCur;
                  pCur = pPre->pNext;
              }
          }
      
      }
      

      我在 C++ 中的回答。

      【讨论】:

        【解决方案5】:

        我在 java 中处理同样的问题,并在最初挣扎后想出了非常小的解决方案。请看一下。

        Node RemoveDuplicates(Node head) {
            Node curr = head;
            if(head==null)
                return head;
            while(curr.next!=null){
                if(curr.data == curr.next.data)
                    curr.next = curr.next.next;
                else curr = curr.next;
            }
            return head;
        }
        

        【讨论】:

          【解决方案6】:

          据我说,您还需要在最后检查您的当前节点是否不是最后一个节点。 这是给出的正确解释和代码: http://www.dscoding.com/2016/11/remove-duplicates-from-sorted-linked.html

          【讨论】:

            猜你喜欢
            • 2022-11-14
            • 1970-01-01
            • 1970-01-01
            • 2013-07-12
            • 2014-12-17
            • 1970-01-01
            • 1970-01-01
            • 2021-10-01
            • 1970-01-01
            相关资源
            最近更新 更多