链表的此自由列表递归函数有什么作用?

时间:2019-04-27 00:32:38

标签: c shell linked-list

我想知道为什么自由列表是递归函数,并且在做什么

typedef struct listint_s
{
    char *a;
    char *b;
    struct listint_s *next;
} listint_t;

void free_list(listint_t *head)
{
    if (head)
    {
        if (head->next)
            free_list(head->next);
        free(head->a);
        free(head);
    }
}

3 个答案:

答案 0 :(得分:0)

此处的递归用于对列表的每个元素进行免费调用。对free_list的第一个调用是处理头节点。第二个调用在head-> next上运行,依此类推。注意,只有在调用free_list(head-> next)后 后才释放输入节点。如果不是这种情况,则链接列表将无法释放head之后的元素。

使用while循环而不是递归可以完成相同的事情:

{
    listint_t *next;
    while (head)
    {
        next = head->next;
        free(head);
        head = next;
    }
    return;
}

答案 1 :(得分:0)

如果您想知道free()本身的功能,请查看How malloc and free work。关于free_list()

这是一个递归函数,因为链表listin_s是)的结构是递归的。即*next本身就是listint_s。因此,它适合于递归操作。只是我们可以将结构定义为“一个包含两个char *的东西,以及一个指向列表其余部分的指针”,我们可以将freeing的操作定义为“释放列表的其余部分,然后释放具有两个内容的那个东西” char *和指向列表其余部分的指针”。带注释:

void free_list(listint_t *head)
{
    if (head) // If this thing is not null
    {
        if (head->next) // If the rest of the list is not null (i.e. we have not reached the end of the list yet)
            free_list(head->next); // Free the rest of the list
        free(head->a); // Then, free the thing pointed to by *a (note for some reason we are not freeing b?)
        free(head); // Then, free this thing
    }
}

答案 2 :(得分:0)

这将释放列表中的所有节点,以及它们从其a成员(但不是b成员)指向的节点。

递归调用首先遍历列表节点,直到到达其head->next元素为NULL的节点为止。

在每个递归调用中,head指向当前元素。递归调用返回后,它将释放head->a指向的内容,然后使用free(head);释放当前元素。

测试if (head->next)是多余的,因为free_list()使用if (head)检查是否在空指针上调用了它。

大多数人迭代而不是递归地编写这种循环,因为在尝试释放一个很长的列表时可能会出现堆栈溢出。

while (head) {
    free(head->a);
    listint_s *temp = head;
    head = head->next;
    free(temp);
}