【问题标题】:Reversing Linked List using recursion algorithm使用递归算法反转链表
【发布时间】:2015-08-29 06:55:03
【问题描述】:

我无法理解反转链表的算法如何修复头指针。

void recursiveReverse(struct node** head_ref)
{
struct node* first;
struct node* rest;

/* empty list */
if (*head_ref == NULL)
   return;   

/* suppose first = {1, 2, 3}, rest = {2, 3} */
first = *head_ref;  
rest  = first->next;

/* List has only one node */
if (rest == NULL)
   return;   

/* reverse the rest list and put the first element at the end */
recursiveReverse(&rest);
first->next->next  = first;  

/* tricky step -- see the diagram */
first->next  = NULL;          

/* fix the head pointer */
*head_ref = rest;              
}

在那之前我都明白了,这是我没有明白的最后一行。
如果列表是 1->2->3。所以,recursiveReverse(2) 会将 *head_ref 设置为 3。但是当它返回 recursiveReverse(1) 时,这里的 rest 指向 2。所以不应该将 *head_ref 设置为 2,(这是不正确的)但它没有实际上。这是如何工作的?

【问题讨论】:

  • 请记住,在递归调用中,变量head_ref 实际上是您传递给递归调用的参数&rest。我建议您在调试器中运行,并逐行逐行执行代码,并单步执行每个递归调用。对于三个或四个节点的小列表,它非常快,应该会给你更多的洞察力。

标签: c algorithm recursion linked-list reverse


【解决方案1】:

当 recursiveReverse(2) 被调用时,recursiveReverse(1) 将 reference 传递给 rest,recursiveReverse(2) 修改为指向 3。然后当 recursiveReverse(1) 设置 *head_ref = rest;rest实际上是指向 3。

【讨论】:

  • 谢谢!这比考虑指针和双指针更容易理解。
【解决方案2】:

另一种解释。在递归调用之前的代码中,在 next to last 嵌套调用中,rest 被设置为指向最后一个节点,而在最后一次调用中,rest 被设置为列表末尾的 NULL,但在这种情况下函数返回而不更新head_ref==rest,所以从recursiveReverse第二次返回后,rest指向最后一个节点,并且不再更新。 “棘手的步骤”并不那么棘手,如果它是一个嵌套调用,那么当 recursiveReverse 返回时, first->next->next 将覆盖它。如果是初始调用,那么第一个节点的 next 指针设置为 null。评论版本:

void ReverseList(NODE**a)
{
NODE *list;     /* will be pointer to reversed list */
    /* NULL check */
    if(a == NULL || *a == NULL)
        return;
    /* recurse until last node is reached */
    list = (*a)->next;
    if (!list)
        return;
    ReverseList(&list);
    /* list now points to what was last node */
    /* reverse a next pointer */
    (*a)->next->next = *a;
    /* set current end of reversed list */
    /*  next gets over written if nested call */
    (*a)->next = NULL;
    /* set pointer to start of reversed list */
    *a = list;
}

返回指针而不是使用双指针的替代版本:

NODE * ReverseList(NODE*a)
{
NODE *list;     /* will be pointer to reversed list */
    /* NULL check */
    if(a == NULL)
        return NULL;
    /* recurse until last node is reached */
    list = a->next;
    if(list == NULL)
        /* return pointer to last node */
        return a;
    list = ReverseList(list);
    /* list now points to what was last node */
    /* reverse a next pointer */
    a->next->next = a;
    /* set current end of reversed list */
    /*  next gets over written if nested call */
    a->next = NULL;
    /* return pointer to what was last node */
    return list;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-22
    • 2018-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-04
    • 1970-01-01
    相关资源
    最近更新 更多