如何删除链表中一行的两个项目

时间:2017-10-19 03:25:17

标签: c++ linked-list

void delete_double (LN<T>*& l) {
    if (l == nullptr)
        return;

    LN<T> *p = l;
    while ( p -> next != nullptr && p -> next -> next != nullptr)
    {
        if (p -> value == p -> next -> value) // the current value is equal to the next value in the linked list 
        {
            if (p == l)                     // when the first two values are the same                                        // not sure if it is correct
            {
                l = l -> next -> next;
            }
            else                            // Problem should be here
            {
                LN<T> *to_delete = p;       //  Also tried this (doesn't work)
                p = p->next;
                delete to_delete;           //  LN<T>* to_delete = p;
                                            //  LN<T>* to_delete2 = p -> next;
                LN<T> *to_delete1 = p;      //  l = to_delete2 -> next;
                p = p->next;                //  delete to_delete;
                delete to_delete1;          //  delete to_delete2;
            }
        }
        else
        {
            p = p-> next;
        }
    }
}
//  Image below is my output

enter image description here

嗨,我正在编写一个函数,如果两个值相同,将删除链表中一行中的两个值。当输入类似于&#34; 1 - &gt;时,我的代码似乎停止工作。 2 - &gt; 3 - &gt; 3 - &gt; 4 - &gt; nullptr&#34;。(输出应该是1 - > 2 - > 4 - > nullptr)。它退出时没有给我任何错误。我逐行完成了调试,只是突然退出并显示&#34;变量不可用&#34;。

我猜这是问题,当我删除p时,l指向垃圾,这会导致问题。所以我尝试了一种不同的方式让我指向to_delete - &gt;下一个。但它仍然无效。

我已经尝试了这么多时间来修复它,调试甚至没有帮助。有人可以帮忙吗?非常感谢!

2 个答案:

答案 0 :(得分:0)

在删除p之前或之后,p之前的项目应指向两个已删除项目之后的项目。否则,链接列表将被破坏。

此外,对于while循环,您可能只在到达最后一个项目时停止。否则,如果最后两个项目相同,则无法正确删除它。

这是我的版本。我使用虚拟项目指向当前比较项目之前的项目。请注意,这不能连续处理3个项目。

void delete_double (LN<T>*& l) {
    if (l == nullptr)
        return;
    LN<T> *dummy = new LN<T>;
    dummy -> next = l;
    while ( dummy -> next != nullptr && dummy -> next -> next != nullptr) // search until the last but two item
    {
        if (dummy -> next -> value == dummy -> next -> next -> value) // the current value is equal to the next value in the linked list
        {
            dummy -> next = dummy -> next -> next -> next;  // link the item after dummy to the item after the deleted items         
        }
        dummy = dummy -> next; // move dummy to the next, notice that this cannot deal with 3 items in a row
    }
    return;
}

答案 1 :(得分:0)

我已经简化了上面的代码,上面的逻辑也无法帮助您删除多个重复项。所以让我们看下面的代码并解析它:

   void delete_double(LN<T>*& l) {

        if (l == nullptr)
            return;

        LN<T> *p = l;
        LN<T> dummy(0);
        dummy.next = l;
        p = &dummy;

        LN<T> *temp;
        LN<T> *duplicate;
        LN<T> *prev;

        while (p != nullptr && p->next != nullptr)
        {
            temp = p;
            while (p != nullptr && temp->next != nullptr)
            {
                if (p->value == temp->next->value)
                {
                    duplicate = temp->next;
                    temp->next = temp->next->next;
                    delete duplicate;

                    duplicate = p;
                    prev->next = p->next;
                    p = prev;
                    delete duplicate;

                    temp = p;
                }
                else
                {
                    break;
                }
            }
            prev = p;
            p = p->next;
        }

        l = dummy.next;
    }

一开始似乎需要一个虚拟节点,因为如果我们有1 - &gt; 1 - &gt; 2我们需要删除前两个并指向正确的头是2。为了避免这种混淆,最好在开始时保持一个虚拟节点,最后只需将列表的输出设置为p = dummy.next,这是列表的实际开始。

我已经定义了一些临时值tempduplicate,temp可以帮助我在列表中进一步导航并复制以保存重复值,将指针移动到next并删除节点。 prev是指向重复项之前的节点的前一个指针。

列表中的每个节点temp = p我向前移动,直到找到相邻的匹配p->value == temp->next->value如果匹配,我删除当前节点和我之前找到的节点。我使用prev跟踪器通过正确设置其next来恢复列表的顺序,否则我会从内部循环中断并继续前进到下一个值,即外部循环p = p->next

我不确定你的LN<T>结构,所以我已经按照我的想法行事。

Demo Link