Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
不理解在C中使用递归反转链表的代码段_C_Data Structures_Recursion_Recursive Datastructures - Fatal编程技术网

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

不理解在C中使用递归反转链表的代码段,c,data-structures,recursion,recursive-datastructures,C,Data Structures,Recursion,Recursive Datastructures,这个程序正在运行。上面提到的递归代码是用于反转单链表。考虑列表L={1,2,3,4,5 }作为输入。考虑两种情况,情况1,如果我们不注释语句10,输出将是最后一个节点的数据,即5×四次,2的情况下,如果我们评论第09条,那么PROTF将打印5,4,3,2。我的问题是,在案例1中,由于这种说法,*头部=休息;为什么每次调用函数都会得到rest->data的常量值?如果我们删除了第09条语句,printf将打印rest->data的不同值。 提前非常感谢。您没有先将连接到返回列表的尾部(rest)。

这个程序正在运行。上面提到的递归代码是用于反转单链表。考虑列表L={1,2,3,4,5 }作为输入。考虑两种情况,情况1,如果我们不注释语句10,输出将是最后一个节点的数据,即5×四次,2的情况下,如果我们评论第09条,那么PROTF将打印5,4,3,2。我的问题是,在案例1中,由于这种说法,*头部=休息;为什么每次调用函数都会得到rest->data的常量值?如果我们删除了第09条语句,printf将打印rest->data的不同值。

提前非常感谢。

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

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

下面是使用递归的工作代码:

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);
}
typedef结构列表{
int数据;
结构列表*下一步;
}名单;
列表*反向(列表**标题)
{
列表*第一,*剩余,*尾;
如果(!*head)返回空值;
第一个=*头;
rest=第一个->下一个;
如果(!rest)首先返回;//新尾部
尾部=反向(和静止);
尾部->下一个=第一个;
first->next=NULL;
*头=休息;
首先返回;//新尾部
//printf(“:%d”,rest->data);
}
内部主(空){
列表[5]={{1,0},{2,0},{3,0},{4,0},{5,0};
列表*头=列表;
int i=0;
对于(;i<4;++i){
列表[i]。下一步=&列表[i+1];
}
反向(头);
返回0;
}
答案就在这里!:-)


这里发生的事情是每次返回函数调用时,“*head=rest;”此语句将使用rest指针的地址更新位置*head(即head指针的地址)处的值,这在程序执行上下文中始终有效。每次函数调用返回的head指针都会更新,这意味着在每次调用之前,rest指针都会更新(请参阅第6行注释)

请修正你的格式
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;
}
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);
}