c - 不理解在 C 中使用递归反转链表的代码片段

标签 c data-structures recursion recursive-datastructures

void reverse(LIST **head)
{
    if(!*head)
      return ;

    LIST *first=*head,*rest=(*head)->next;
    if(!rest)
      return;

    reverse(&rest);
    first->next->next = first;
    first->next= NULL;
    *head = rest;                                                             
    // printf("   :%d",rest->data);
}

该程序正在运行。上述递归代码用于反转单链表。考虑一个列表 L={1,2,3,4,5} 作为输入。考虑两种情况,情况 1 如果我们取消注释语句 10,输出将是最后一个节点的数据即 5 四次,情况 2 如果我们评论语句号。 09 那么 printf 将打印 5,4,3,2。我的问题是,在情况 1 中,由于这个语句 *head=rest;为什么我们每次调用函数时都会得到rest->data的恒定值?如果我们删除声明号。 09 然后printf将打印rest->data的不同值。
提前非常感谢您。

最佳答案

您没有将first连接到返回列表的尾部(rest)。一种简单的反转方法是使用数组来存储所有元素并以相反的顺序迭代数组 - 就像堆栈一样。

使用递归的另一个选项是从反向返回“尾部”。一旦有了尾部,就可以很简单地首先连接到它并返回它(因为 first 是新的尾部)。

这是使用递归的工作代码:

typedef struct LIST {
    int          data;
    struct LIST *next;
} LIST;

LIST* reverse(LIST **head)
{
    LIST *first, *rest, *tail;
    if (!*head) return NULL;

    first = *head;
    rest = first->next;

    if (!rest) return first; // new tail

    tail = reverse(&rest);
    tail->next = first;
    first->next = NULL;

    *head = rest;                                                             
    return first; // new tail
    // printf("   :%d",rest->data);
}

int main(void) {
    LIST list[5] = { {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}}; 
    LIST *head = list;
    int i = 0;
    for (; i < 4; ++i) {
        list[i].next = &list[i+1];
    }
    reverse(&head);
    return 0;
}

关于c - 不理解在 C 中使用递归反转链表的代码片段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20584997/

相关文章:

javascript - 递归删除所有具有空值的 JSON 键,如果所有子键都被删除,则删除父键

haskell - 下面的函数尾调用优化了吗?

c - 包含指针变量的 C 程序输出

c - 维护指向地址的指针链

java - 是否可以在堆栈上使用提供的 Java 集合方法,例如 max、min、sort 等...?

c - 我在代码块中编写的堆栈实现代码编译成功,但在运行时显示错误

c - 传递一个二维结构数组

c - 如何从 unsigned char 转换为 long

java - 修改其副本时保持原始 Vector 完整

list - 如何对 Prolog 列表的元素执行算术运算