【问题标题】:Remove Duplicates linked list删除重复链表
【发布时间】:2020-05-15 08:22:43
【问题描述】:
void RemoveDuplicates(Slist& l)
{
    if (l.head == NULL) {
        return;
    }
    Node* cur = l.head;
    while (cur != NULL && cur->next != NULL) {
        Node* prev = cur;
        Node* temp = cur->next;
        while (temp != NULL) {
            if (temp->data == cur->data) {
                prev->next = temp->next;
                cur->next = prev->next;
                temp = prev->next;
            }
            else {
                prev = prev->next;
                temp = temp->next;
            }
        }
        cur = cur->next;
    }
}

您好,我想从链表中删除重复项(0 为 NULL)

input:  1->2->2->4->2->6->0 
outPut: 1->2->4->6->0

我运行程序后的结果是:

1->2->6

我哪里错了?请帮帮我

【问题讨论】:

  • 删除的节点分配的内存在哪里?
  • 显示列表定义。例如,不清楚您是否定义了指向尾节点的指针。
  • 您应该使用调试器并在纸上可视化每个步骤,看看会发生什么。你有cur,它在你搜索重复项的内部循环中不会改变,但是当你找到重复项时你也有cur->next = prev->next,这是不对的。
  • 首先,您可能没有考虑这个问题足够长的时间。您想删除4 之后的2,因为4 之前有一些2。这意味着您需要比较 非相邻 节点。你注意到了吗……?恕我直言,您至少可以通过两种方式处理它:1.您可以遍历整个列表,并且对于仍在列表中的每个节点“c”扫描所有剩余节点并删除等于当前“c”的节点。这具有平方复杂度。 2. 或者先对整个列表进行排序(这个阶段有对数线性复杂度),然后扫描并移除相邻的重复项(线性)。

标签: c++ linked-list


【解决方案1】:

这是我的解决方案:

bool alreadyExist(Node head)
{
    Node cur = head;
    while(cur.next != nullptr)
    {
        if(cur.next->data == head.data) {
            return true;
        }
        cur = *cur.next;
    }

    return false;
}

void RemoveDuplicates(Slist& l)
{
    if (l.head == nullptr) {
        return;
    }

    Node* head = l.head;

    Node* curPtr = l.head->next;
    while(curPtr != nullptr)
    {
        if(alreadyExist(*curPtr) == false)
        {
            head->next = curPtr;
            head->next->prev = head;
            head = head->next;
            curPtr = curPtr->next;
        }
        else
        {
            Node* backup = curPtr;
            curPtr = curPtr->next;

            // delete duplicate elements from the heap,
            // if the nodes were allocated with new, malloc or something else
            // to avoid memory leak. Remove this, if no memory was allocated
            delete backup;
        }
    }
}

重要提示:Node对象的析构函数不允许删除next和prev指针后面的链接对象。

对于您的输入示例,它会导致输出 1->4->2->6->0。它不完全准确的顺序,你想要作为输出,但每个数字在输出中只存在一次。它只添加重复号码的最后一次。 我真的不知道,如果你使用 C 或 C++,但因为我更喜欢 C++,所以我在代码中用 nullptr 替换了 NULL。如果对象不在使用 malloc 或 new 创建的 HEAP 上,则可以删除删除。

【讨论】:

  • 谢谢大家。今天早上我解决了我的问题^^。感谢您的帮助
猜你喜欢
  • 1970-01-01
  • 2021-05-13
  • 1970-01-01
  • 2015-09-10
  • 1970-01-01
  • 2013-12-14
  • 1970-01-01
相关资源
最近更新 更多