繁体   English   中英

使用递归反向链表

[英]reverse linked list using recursion

我正在尝试使用递归来反向链接列表。 我制作了reverse()函数来反转列表。 我在main()创建了一个链表,还定义了print()方法。 我不知道我在犯什么错误。 请帮我改正。 下面给出了代码片段。

struct node
{
    int data;
    struct node *next;
}*head;

void reverse(node **firstnode,node *n)
{
    if(n==NULL)
    {
        head=n;
        return;
    }
    reverse(&head,n->next);
    struct node *q=n->next;
    n->next=q;
    q->next=NULL;
}

void main()
{
    ......

    head=first;
    reverse(&first,first);
    print(head);
}

它可能无法直接解决您的问题。 但是,您在标记中提到了C ++ 11。 因此,请看一下std :: forward_list 它是基于单个链表的标准容器。

我认为您在反向功能的末尾混合了地址,它可能看起来像:

q->next=n;
n->next=NULL;

另外,我不确定是否需要“ firstnode”参数。

List* recur_rlist(List* head)
{
    List* result;
    if(!(head && head->next)) 
        return head;

    result = recur_rlist(head->next);
    head->next->next = head;
    head->next = NULL;

    return result;
}

void printList(List* head)
{
    while(head != NULL) {
        std::cout<<head->data<<" ";
        head = head->next;
    }
}
void main()
{
    List* list = createNode(2);
    append(list, createNode(3));
    append(list, createNode(4));
    append(list, createNode(5));
    append(list, createNode(6));
    List* revlist = recur_rlist(list);
    printList(revlist);
}

由于您想了解代码,并且已经拥有许多精通代码的资源,因此不需要更多的精制代码示例。 我将回答一些概念,并指出需要修复的错误。

首先,一些背景概念。

链接列表:第一和休息

任何链表要么为空,要么可以分解为第一个(节点)和其余(一个较小的链表,或者为空)。 这使得递归容易得多。

if (head){
    node * first = head;
    node * rest  = head->next;
}

不变的(简化的):保证在您的函数开始和结束时始终为真。

在链接列表中,您希望头部指向一个节点,该节点指向另一个节点,依此类推,直到到达末尾为止(由nullptr表示)。 所有节点都不同。 所有节点均有效。 这些是在调用函数之前和函数返回时必须为真的保证。

在递归函数中,不变量必须保持在每一步都要反转的子列表中,因为您在每一步都从函数中返回。 但这使递归更加容易,因为您要做的就是确保如果输入正确,则函数将在当前步骤返回良好的值。

递归结束:通过结合前面的概念,您可以证明递归函数永远不会陷入无限循环。 如果不变量保持不变,则每个步骤都将起作用,并且由于每个递归调用都将休息(这保证为nullptr或更短的列表),所以最终我们必须到达终点。 当然,这表明您可以应付一切。

好的,关于实际问题:

您没有正确处理递归结束。 您只需在最后设置head = nullptr,我很确定那不是您想要的head。 您可能要处理if(nullptr == n-> next)的结尾,因为那样您就知道那是最后一个节点。 当然,您仍然必须正确处理nullptr == head的琐碎情况。

您不保留不变式。 您曾经尝试过,但是看来您的簿记是完全错误的。 我建议您使用调试器或3x5记录卡逐步完成修改交换内容的实际工作。 例如,看起来您只是在混淆此代码片段中的哪个节点:

struct node *q=n->next;   // n is first, q is rest
// what if nullptr == q?
n->next=q;                // n->next = n->next doesn't actually change anything
q->next=NULL;             // this must already be true if reverse(rest) did its job
// q and n were swapped?

同样,您的函数使用“ firstnode”,但不使用它,而是将全局变量“ head”设置为副作用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM