【问题标题】:How does this recursive function free the tree这个递归函数如何释放树
【发布时间】:2022-11-10 14:17:27
【问题描述】:
    #include <stdio.h>
    #include <cs50.h>
    #include <stdlib.h>

    typedef struct node{
        int number;
        struct node* right;
        struct node* left;
    }node;

    void print_tree(node* root);

    int main(void){
        node* tree = NULL;  // creating a starting point

        node* n = malloc(sizeof(node));  // creating the root of the tree
        if(n == NULL){
            return 1;
        }
        n->number = 2;
        n->right = NULL;
        n->left = NULL;
        tree = n;

        n = malloc(sizeof(node));  // creating the right branch
        if(n == NULL){
            return 1;
        }
        n->number = 3;
        n->right = NULL;
        n->left = NULL;
        tree->right = n;

        n = malloc(sizeof(node));  // creating the left branch
        if(n == NULL){
            return 1;
        }
        n->number = 1;
        n->right = NULL;
        n->left = NULL;
        tree->left = n;

        print_tree(tree);  // input tree as a parameter for the function
    }

    void print_tree(node* root){
        if(root == NULL){
            return;
        }
        print_tree(root->left);  // it prints number 1
        printf("%i\n", root->number); // it prints number 2
        print_tree(root->right);  // it prints number 3
        free(root);  // it frees all of them 
    }

这段代码是 C 语言中的一棵树,我没有问题。我要问的是函数如何使用递归释放这些字节? 它如何读取函数?

【问题讨论】:

  • 它调用print_tree(root-&gt;left); 释放左节点。然后它调用print_tree(root-&gt;right); 释放正确的节点。然后它调用free(root); 释放当前节点。
  • 我宁愿问:为什么一个函数叫print_xy释放任何内存。那是不行的。
  • print_tree() 函数是 I/O 和内存管理的可恶组合。它应该是两个独立的函数,一个打印树,另一个释放树。
  • 您的代码注释“// 它释放了所有节点”传达了您误解的可能来源:释放所有节点的不是对 free() 的一次调用。释放所有节点采取联合行动全部free() 的调用由全部print_tree() 的处决。由于您可以从输出中看到 print_tree() 为每个节点调用一次,因此不难理解这会导致每个节点调用一次 free()
  • 将其描述为“开始[ing]函数”很容易引起误解。我更愿意说每个递归调用都执行一个分离,完全的使用指定参数执行函数。当然,这可能包括额外的递归调用。

标签: c recursion tree cs50


【解决方案1】:

当您调用函数 print_tree(tree) -> 它将按顺序从根调用节点 1 和 3,free 语句将释放左节点,然后是右节点。最后,它释放导致调用节点 1 和 3 的节点,即根节点。
您可以通过在两个递归调用之后放置“cout”运算符来检查这一点,它可能会打印 1 然后 3 然后 2。

【讨论】:

    猜你喜欢
    • 2015-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-13
    • 2015-08-21
    相关资源
    最近更新 更多