在C语言中递归删除单链表

在C语言中递归删除单链表,c,recursion,linked-list,C,Recursion,Linked List,看起来没有重复的问题…所以我想要一个函数来释放单个链表中的所有节点,并且我想要递归地这样做。我想出了一个很接近的方法,我认为它会奏效,但它没有。似乎在移除一个节点后,上层堆栈函数将不会以递归的方式原谅它。我想知道如何修改代码使其工作 #include <stdlib.h> #include<stdio.h> #include<stdlib.h> struct Node { int data; struct Node *next; }; void

看起来没有重复的问题…所以我想要一个函数来释放单个链表中的所有节点,并且我想要递归地这样做。我想出了一个很接近的方法,我认为它会奏效,但它没有。似乎在移除一个节点后,上层堆栈函数将不会以递归的方式原谅它。我想知道如何修改代码使其工作

#include <stdlib.h>
#include<stdio.h>
#include<stdlib.h>

struct Node 
{
  int data;
  struct Node *next;
};

void ft_list_clear(struct Node *begin_list)
{
    if ((begin_list->next))
      ft_list_clear(begin_list->next);
    if(!(begin_list->next))
    {
      free(begin_list);
      begin_list = NULL;
    }
}

int main()
{
  struct Node* head = NULL;
  struct Node* second = NULL;
  struct Node* third = NULL;

  // allocate 3 nodes in the heap  
  head  = (struct Node*)malloc(sizeof(struct Node)); 
  second = (struct Node*)malloc(sizeof(struct Node));
  third  = (struct Node*)malloc(sizeof(struct Node));

  head->data = 1; //assign data in first node
  head->next = second; // Link first node with second   

  second->data = 2; //assign data to second node
  second->next = third;  

  third->data = 3; //assign data to third node
  third->next = NULL;

  ft_list_clear(head);
  return 0;
}
#包括
#包括
#包括
结构节点
{
int数据;
结构节点*下一步;
};
无效ft\u列表\u清除(结构节点*开始\u列表)
{
如果((开始列表->下一步))
ft\u列表\u清除(开始列表->下一步);
如果(!(开始列表->下一步))
{
免费(开始列表);
begin_list=NULL;
}
}
int main()
{
结构节点*head=NULL;
结构节点*second=NULL;
结构节点*third=NULL;
//在堆中分配3个节点
head=(结构节点*)malloc(sizeof(结构节点));
第二个=(结构节点*)malloc(sizeof(结构节点));
第三个=(结构节点*)malloc(sizeof(结构节点));
head->data=1;//在第一个节点中分配数据
head->next=second;//将第一个节点链接到第二个节点
第二个->数据=2;//将数据分配给第二个节点
第二->下一个=第三个;
第三->数据=3;//将数据分配给第三个节点
第三->下一步=空;
ft_列表_清除(标题);
返回0;
}
你很接近了

void ft_list_clear(struct Nude *list)
{
   if (!list) { return; }

   ft_list_clear(list->next);
   list->next = null;
   free(list);
}
解释代码

第一个
if
检查列表当前是否为
null
,如果是,则退出递归

如果列表不是
null
递归调用该函数。 此操作将重复,直到列表的末尾
null
。 然后,由于递归调用已清除了
下一个
,因此您可以在此调用中将其设置为
null
(由于这会清除所有内容,因此严格来说不需要)。 最后,在返回到上一个调用(该节点的父节点)之前,实际释放该节点

如果需要,也可以按相反的顺序执行删除

void ft_list_clear(string Node *list)
{
   if (!list) { return; }
   struct Node *next = list->next;
   free(list);
   ft_list_clear(next);
}
相同的原则只是在转到下一个节点之前删除此节点。这意味着您不需要修复下一个指针,但您需要先复制它们,以免丢失引用。

您已经非常接近了

void ft_list_clear(struct Nude *list)
{
   if (!list) { return; }

   ft_list_clear(list->next);
   list->next = null;
   free(list);
}
解释代码

第一个
if
检查列表当前是否为
null
,如果是,则退出递归

如果列表不是
null
递归调用该函数。 此操作将重复,直到列表的末尾
null
。 然后,由于递归调用已清除了
下一个
,因此您可以在此调用中将其设置为
null
(由于这会清除所有内容,因此严格来说不需要)。 最后,在返回到上一个调用(该节点的父节点)之前,实际释放该节点

如果需要,也可以按相反的顺序执行删除

void ft_list_clear(string Node *list)
{
   if (!list) { return; }
   struct Node *next = list->next;
   free(list);
   ft_list_clear(next);
}
相同的原则只是在转到下一个节点之前删除此节点。这意味着您不需要修复下一个指针,但需要先复制它们,以免丢失引用。

`void ft\u list\u clear(结构节点*begin\u list)

希望,如果上帝保佑美国三次,你的代码是有效的,我在你的代码中做了一些更改,我所做的只是删除了第二个if语句,因为在递归中通常不需要它(我不是说我们不需要多个if语句)。自己测试一下,你就会明白为什么会这样。希望有帮助。

`void ft\u list\u clear(结构节点*开始列表)


希望,如果上帝保佑美国三次,你的代码是有效的,我在你的代码中做了一些更改,我所做的只是删除了第二个if语句,因为在递归中通常不需要它(我不是说我们不需要多个if语句)。自己测试一下,你就会明白为什么会这样。希望能有所帮助。

我认为这是因为您只是释放了节点,但没有取消
下一个成员的
。试试这个。我从来没有这么好运

void ft_list_clear(struct Node *begin_list)
{
    if ((begin_list->next))
    {
      ft_list_clear(begin_list->next);
      begin_list->next = NULL; // <-- you should nullify the next of the current after you free the node which it points to.
    }
    if(!(begin_list->next)) // <-- even if the next node was deleted, this won't run if you didn't nullify begin_list->next
    {
      free(begin_list);
      begin_list = NULL;
    }
}
void ft\u list\u clear(结构节点*开始列表)
{
如果((开始列表->下一步))
{
ft\u列表\u清除(开始列表->下一步);
begin_list->next=NULL;//next))//next
{
免费(开始列表);
begin_list=NULL;
}
}

我认为这是因为您只是释放了节点,但是您没有取消
下一个成员的
。试试这个。我没有运行这个,祝您好运

void ft_list_clear(struct Node *begin_list)
{
    if ((begin_list->next))
    {
      ft_list_clear(begin_list->next);
      begin_list->next = NULL; // <-- you should nullify the next of the current after you free the node which it points to.
    }
    if(!(begin_list->next)) // <-- even if the next node was deleted, this won't run if you didn't nullify begin_list->next
    {
      free(begin_list);
      begin_list = NULL;
    }
}
void ft\u list\u clear(结构节点*开始列表)
{
如果((开始列表->下一步))
{
ft\u列表\u清除(开始列表->下一步);
begin_list->next=NULL;//next))//next
{
免费(开始列表);
begin_list=NULL;
}
}
这个问题

void ft_list_clear(struct Node *begin_list)
{
    if ((begin_list->next))
      ft_list_clear(begin_list->next);
    if(!(begin_list->next))
    {
      free(begin_list);
      begin_list = NULL;
    }
}
是:

  • 在第一次调用中,
    begin\u list
    等于
    head
  • head->next
    不是
    NULL
    ,因此执行
    ft\u list\u clear(second)
  • second->next
    不是
    NULL
    ,因此执行
    ft\u list\u clear(third)
  • third->next
    NULL
    ,因此发生了
    free(third)
    begin\u list=NULL
    线条在这里什么都不做,毫无意义
  • 第三次迭代返回第二次

    if(!(begin_list->next))
    
    begin\u list->next
    notNULL(它只是
    free
    d),因此该条件被评估为
    false
    ,而
    free
    没有执行

  • 第一次迭代也会发生同样的情况
这是可以工作的递归:

void ft_list_clear(struct Node *begin_list)
{
    if(begin_list == NULL)
        return;

    ft_list_clear(begin_list->next);
    free(begin_list);
}
这个问题是什么

void ft_list_clear(struct Node *begin_list)
{
    if ((begin_list->next))
      ft_list_clear(begin_list->next);
    if(!(begin_list->next))
    {
      free(begin_list);
      begin_list = NULL;
    }
}
是:

  • 在第一次调用中,
    begin\u list
    等于
    head
  • head->next
    不是
    NULL
    ,因此执行
    ft\u list\u clear(second)
  • second->next
    不是
    NULL
    ,因此执行
    ft\u list\u clear(third)
  • third->next
    NULL
    ,因此发生了
    free(third)
    begin\u list=NULL
    线条在这里什么都不做,毫无意义