使用递归算法反转链接列表

时间:2015-08-29 06:55:03

标签: c algorithm recursion linked-list reverse

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

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,(这是不正确的)但它不会其实。这是如何工作的?

2 个答案:

答案 0 :(得分:1)

当调用recursiveReverse(2)时,recursiveReverse(1)传递一个引用到rest,recursiveReverse(2)修改为指向3.然后当recursiveReverse(1)设置{{1}时} rest实际上指的是3。

答案 1 :(得分:1)

另一种解释。在递归调用之前的代码中,在最后一个嵌套调用的下一个中,rest被设置为指向最后一个节点,而在最后一个调用中,rest被设置为列表末尾的NULL,但在这种情况下,函数返回而不更新head_ref == rest,所以在从recursiveReverse返回第二个之后,rest指向最后一个节点,并且永远不会再次更新。 “棘手的步骤”并不是那么棘手,如果它是嵌套调用,那么当recursiveReverse返回时,first-> 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;
}