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

时间:2013-12-14 15:25:46

标签: 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}作为输入。考虑两种情况,如果我们取消注释语句10则为情况1,输出将是最后一个节点的数据即5个四次,如果我们评论声明没有案例2。 09然后printf将打印5,4,3,2。我的问题是,在案例1中由于这个陈述* head = rest;为什么我们得到每次调用函数的rest->数据的常数值?如果我们删除了声明号。 09然后printf将打印不同的rest->数据值  非常感谢你。

2 个答案:

答案 0 :(得分:1)

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

使用递归的另一个选项是从reverse返回'tail'。一旦你有了尾部,首先连接到它并返回它是很简单的(因为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;
}

答案 1 :(得分:0)

这是答案! :-)

void reverse(LIST **head) 

{     

   01:    if(!*head)
   02:      return ;

   03:    LIST *first=*head,*rest=(*head)->next;
   04:    if(!rest)
   05:      return;
   06:    reverse(&rest); //head pointer in new function call context is a rest pointer in previous function call context.  

  07:    first->next->next = first;
  08:    first->next= NULL;
  09:    *head = rest;


  10:    // printf("   :%d",rest->data);
}

这里发生的是每次返回函数调用时,“* head = rest;”此语句正在更新位置* head(它是头指针的地址)的值,其中包含rest指针的地址,这在程序执行上下文中起作用。每次函数调用返回头指针都会更新,意味着每个先前的调用休息指针都会更新(参见第6行注释)。