其他分享
首页 > 其他分享> > c-如何在链表中连续删除两项

c-如何在链表中连续删除两项

作者:互联网

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

嗨,我正在编写一个函数,如果两个值相同,它将在链接列表的一行中删除两个值.当输入类似于“ 1-> 2-> 3-> 3-> 4-> nullptr”时,我的代码似乎停止工作.(输出应为1-> 2-> 4 -> nullptr).它退出时没有给我任何错误.我逐行通过调试,它突然退出并显示“变量不可用”.

我猜这是问题,当我删除p时,l指向垃圾,这会导致问题.因此,我尝试了另一种方法使l指向to_delete->下一个.但这仍然行不通.

我已经尝试了许多小时来修复它,而调试甚至都无济于事.有人可以帮忙吗?非常感谢!

解决方法:

我已经简化了上面的代码,上面的逻辑也无法帮助您删除多个重复项.因此,让我们看下面的代码并进行剖析:

   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->,则为1. 1-> 2我们需要删除前两个,并指向正确的头部2.为了避免这种混淆,最好在开始时保留一个虚拟节点,最后将列表的输出设置为p = dummy.next,它是列表的实际开始.

我已经定义了一些临时变量,临时变量和重复变量,以帮助我在列表中进行进一步的导航,并使用临时变量来保留重复的值,将指针移至下一个并删除节点. prev是指向重复项之前节点的上一个指针.

列表中的每个节点temp = p我继续前进,直到找到相邻的匹配p-> value == temp-> next->值(如果存在匹配项),我删除当前节点,然后删除前面找到的那个节点它的.我使用prev跟踪程序通过正确设置列表的下一个来恢复列表的顺序,否则我从内部循环中断并继续执行下一个值,即外部循环p = p-> next.

我不确定您的LN< T> struct,所以我按照我的想法前进了.

Demo Link

标签:c,linked-list
来源: https://codeday.me/bug/20191013/1909079.html