【问题标题】:linked list - elements come after removing链表 - 元素在删除后出现
【发布时间】:2020-03-16 22:04:57
【问题描述】:

我有一个Node 类来实现链表:

class Node
{
    public:
        int data;
        Node *next;
        Node(int d){
            data=d;
            next=NULL;
        }
};

在解决方案类中,我有插入、删除重复项、打印等方法;

现在removeDuplicates 我的逻辑是:

  • 如果我当前的下一个节点为空,则返回
  • 如果当前的值等于当前的下一个值,则设置为当前的下一个
  • 用下一个递归

这是我的代码:

Node* removeDuplicates(Node* head)
        {
            process(head);
            return head;
        }

        void process(Node* node)
        {
            cout << node->data << endl;
            if(node->next==NULL)
                return;
            if(node->data==node->next->data)
                node=node->next;
            process(node->next);
        }

当我调用removeDuplicate 方法时,它会打印: 1 2 3 4 正如预期的那样,但在那之后,当我再次使用我的另一种方法打印时,它给了我整个链表,而不删除重复项: 1 2 2 3 3 4

display方法:

void display(Node *head)
          {
                  Node *start=head;
                    while(start)
                    {
                        cout<<start->data<<" ";
                        start=start->next;
                    }
           }

【问题讨论】:

  • 您的观察是正确的。如图所示,重复删除代码完全没有任何作用,也不会更改链接列表中的任何内容。由于链接列表仅通过next 指针存在(仅它们将列表中的元素链接在一起),因此对列表中内容的任何更改显然都需要以某种方式更改next 指针。这是更改列表中内容的唯一方法。而且,在所有删除重复项的代码中,我没有看到任何一行代码实际更改了任何 next 指针。这就是为什么你的代码什么都不做的原因。
  • 同意山姆。在这个带有 line node = node->next 的代码中,您实际上是在使节点指针指向列表中的下一个元素(而不是修改列表)。必须做这样的事情 temp = node-> next;节点=节点->下一个->下一个;免费(临时);这使得当前节点指针指向下一个下一个节点(这将是删除下一个节点时的下一个节点 temp 指向下一个将在病房后释放的节点。)
  • 您永远不会更改列表(node = node-&gt;next 只是更改该函数的局部变量,而不是列表中的任何内容)
  • 也许node-&gt;next = node-&gt;next-&gt;next; 是您想要的,但请记住,在这种情况下,您希望从当前节点(而不是下一个节点)继续处理,以防连续三个相同的节点元素。当然,假设在这种情况下预期的行为是将所有三个压缩为一个。
  • while(head-&gt;next!=NULL) { head=head-&gt;next; } return head; 如果我使用这个内部进程,为什么我只得到最后一个元素?

标签: c++ c++11 pointers linked-list


【解决方案1】:

问题出在你的进程函数中,请看下面的修改代码

 void process(Node* node)
 {
    cout << node->data << endl;
    if(node->next==NULL)
       return;
    if(node->data==node->next->data) {

       Node *tmp = node->next; 
       node->next = tmp->next;   
       delete(tmp); 
       //  node=node->next;

    }
    process(node->next);
 }

【讨论】:

    【解决方案2】:

    以下显示的行来自您的代码,您在其中实现了当有重复项时要执行的操作。

     if(node->data==node->next->data)
           node=node->next;
    

    所以你在这里做的是让节点指针移动到下一个节点。您应该编写代码,以便在重复的情况下跳过下一个节点,并且您只能通过操作当前节点的下一个指针来做到这一点。如下图所示:

     if(node->data==node->next->data)
           node->next=node->next->next;
    

    【讨论】:

      【解决方案3】:

      如果您想保留代码的逻辑并获得预期的结果,您只需添加一个字符即可。 你需要更换

      void process(Node* node) {...}
      

      void process(Node*& node) {...}
      

      输出将如你所愿。

      【讨论】:

        猜你喜欢
        • 2017-12-28
        • 2020-08-13
        • 1970-01-01
        • 2021-02-25
        • 2021-12-31
        • 1970-01-01
        • 2021-05-14
        • 2015-10-25
        • 2023-03-16
        相关资源
        最近更新 更多