【问题标题】:Whats the issue with my code for Linked List reversal Recursive Method?我的链表反转递归方法的代码有什么问题?
【发布时间】:2018-02-18 10:21:46
【问题描述】:

我正在尝试使用递归来反转链表。当我在反转后显示列表时,我只得到原始列表的第一个元素 `

        void reve(node *a,node *b,node *c,node *h1)
       {
               if(c->next==NULL)
           {
               c->next=b;
               b->next=a;
                return ;
           }

           reve(a->next,b->next,c->next,h1);
           c->next=b;
           b->next=a;
           if(a==h1)
         {
            a->next=NULL;
         }

         return ;

      }` 

【问题讨论】:

  • 你调试了吗?

标签: c++ c++11 recursion data-structures linked-list


【解决方案1】:

这是因为你的调用代码仍然持有一个指向曾经是第一个节点的指针,但该节点现在是最后一个。
(至少如果代码确实有效的话——很难跟踪所有这些参数,而且它们的关系就像它们的名字一样神秘。)

如果您返回一个指向新头的指针,这将更容易实现。
您也只需要一 (1) 个参数。

那么你需要处理三种情况:

  1. 空列表——只返回空列表;
  2. 单例列表 - 只需返回即可;
  3. 一般情况。

您可以通过首先反转列表的其余部分,接收新的头部来解决一般情况。

那么你需要让“新的最后一个元素”的next指向“这个”节点,以便让“这个”节点成为反向列表的下一个元素。
这比听起来要容易——从递归中得到的反向列表中的最后一个节点仍然是该节点的 next 节点。
(如果不清楚,请在纸上画出来。)

然后您还需要通过将其next 归零来使“this”节点终止列表。

然后返回你从递归中得到的“新头”。

node* reverse(node* n)
{
    // Empty list:
    if (!n)
    {
        return nullptr;
    }
    // Singleton list:
    if (!n->next)
    {
        return n;
    }
    // General case:
    node* head = reverse(n->next); // Reverse the rest,
    n->next->next = n;             // Attach this node at the end,
    n->next = nullptr;             // Terminate the list,
    return head;                   // Done.
}

【讨论】:

  • 可以将前两个案例压缩为if (!n || !n->next) { return n; },但我不确定这样是否更好
  • 我想在代码中保留“三种情况”结构(我养成了使用模式匹配语言的习惯)。单独推理每个案例并说服自己它是正确的更容易。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-24
  • 2012-11-26
  • 1970-01-01
  • 2017-01-23
  • 2014-04-18
  • 1970-01-01
  • 2016-04-23
相关资源
最近更新 更多