C 将头引用标记为链接列表的尾部

C 将头引用标记为链接列表的尾部,c,linked-list,C,Linked List,反转链表的迭代方法非常简单。我通过下面的链接试图理解递归方法 我们首先将指针移动到链表的尾部。 在堆栈展开期间,我们反向缝合链接。 但对于所有堆栈展开调用,*headref=rest。既然第一个在堆栈展开期间更改为上一个堆栈值,为什么其余的也没有更改呢。我创建了4个节点,并通过gdb查看了这些值。堆栈展开期间的剩余值保持不变,但第一个值正在更改。为什么它没有改变 从改变指针和值的角度思考是一个好方法 考虑迭代程序,这是一种令人困惑的方法 递归程序,因为每个递归调用都创建自己的本地 变量,所有变

反转链表的迭代方法非常简单。我通过下面的链接试图理解递归方法

我们首先将指针移动到链表的尾部。 在堆栈展开期间,我们反向缝合链接。
但对于所有堆栈展开调用,*headref=rest。既然第一个在堆栈展开期间更改为上一个堆栈值,为什么其余的也没有更改呢。我创建了4个节点,并通过gdb查看了这些值。堆栈展开期间的剩余值保持不变,但第一个值正在更改。为什么它没有改变

从改变指针和值的角度思考是一个好方法 考虑迭代程序,这是一种令人困惑的方法 递归程序,因为每个递归调用都创建自己的本地 变量,所有变量的名称相同,但值可能不同

对于递归函数,假设它对大小为
n
的输入正确工作,然后对大小为
n+1
的输入验证其正确性更为有用。如果覆盖了“基本情况”(大小0或1),则证明它适用于所有输入

在您的例子中,我们假设
recursiverse
对于长度为3的列表可以正常工作,并通过以下方式为其提供长度为4的列表
a->b->c->d
调用递归变量(&p)其中
p=a

first->next
rest
都将是
b
,因此指向一个三元素列表
b->c->d
,因此(根据我们的假设)
recursiverse(&rest)
将正确反转此列表。之后 调用时,
rest
已将值(从
b
更改为
d
),现在指向此反向列表
d->c->b

first->next
仍然是调用之前相同的指针
b
,因此现在指向列表的末尾。 因此,
first->next->next=first
first
附加到该反向列表的末尾,然后该列表变为
d->c->b->a
) 由于
first
现在是列表的末尾,我们现在需要
first->next=NULL
。最后一步是更改
*head\u ref
(从
a
更改为
d
),因此,从
recursiverse(&p)
返回后,
p
将从
a
更改为列表的新head,
d

这表明,只要函数对n元素正确工作 列表,它可以正确地用于n+1元素列表。基本情况很简单, 所以我们已经证明它适用于所有列表

现在,为什么不在调试器中看到
rest
正在更改值?因为 其值仅通过函数调用更改
recursiverse(&rest)
。在你递归调用之前
recursiverse
它有一个值,从它返回后,它有一个值 另一方面,当您在每个函数调用中进出时,您看不到它的变化。更改其值的赋值实际上是函数返回之前的最后一个(
*head\u ref=rest
),但是在这个堆栈帧中调用受让人的是
head\u ref
,而不是
rest
(在调用方的堆栈帧中调用)

这就是我上面提到的“名称相同,但值不同”的混淆

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;              
}