【问题标题】:Preorder tree traversal function which returns an array of integers in C在 C 中返回整数数组的前序树遍历函数
【发布时间】:2016-09-25 16:16:30
【问题描述】:

我尝试编写一个函数,它返回一个整数数组,该数组包含二叉树的节点值,即节点值必须出现在其左右子节点的值之前。

  • 如果 root 为 NULL,则返回 NULL

  • 对于每个节点,左孩子都在右孩子之前

例如;

int *a = preorder(bt1);
for (i=0; i<3; i++)
    printf("%d ", a[i]);
>2_1_3_

这是我的工作,但它不起作用,我的代码可能出在哪里?

int* preorder(TreeNode *root) {
    int *a = malloc(sizeof(int)*50);
    int i=0;

    if(root == NULL)
        return NULL;
    else {
        if(root != NULL) {
            a[i] = root->val;
            i++;
            preorder(root->left);
            preorder(root->right);
            return a;
        }
    }
}

【问题讨论】:

  • 分配没有意义。究竟是什么不清楚?
  • 每次调用preorder 都会将结果存储到一个不同的数组中。这显然不是你想要的。您需要将数组传递给每个preorder 调用。

标签: c binary-tree


【解决方案1】:

使用preorder() 的所需函数签名是不可能的。因此,您需要一个用于root == NULL 案例的辅助函数和一个指向数组中当前位置的指针的遍历函数。它还返回指向数组中下一个空闲槽的指针。解决方案可能如下所示:

#include <stdio.h>
#include <malloc.h>

struct TreeNode {
    int val;
    struct TreeNode* left, * right;
};

int tree_size(/*struct TreeNode* tree*/) { return 7; }

int* preorder_(struct TreeNode* tn, int* v) {
    *v++ = tn->val;
    if (tn->left) v = preorder_(tn->left, v);
    if (tn->right) v = preorder_(tn->right, v);

    return v;
}

int* preorder(struct TreeNode* tn) {
    if (tn) {
        int* v = malloc(tree_size(/*tn*/) * sizeof(int));
        preorder_(tn, v);
        return v;
    } else {
        return NULL;
    }
}

int main(void) {
    //    4
    //  2   5
    // 1 3 6 7
    struct TreeNode
        left = {2, &{1}, &{3]}, 
        right = {5, &{6}, &{7}}, 
        root = {4, &left, &right};
    int *v, i;

    v = preorder(&root);
    for (i = 0; i < tree_size(/*tn*/); i++) {
        printf("%d ", v[i]); // 4 2 1 3 5 6 7
    }
    free(v);

    return 0;
}

Live Demo

【讨论】:

    【解决方案2】:

    代码中有两个问题:

    1. 您必须为结果分配一次数组。打电话之前preorder
    2. 您必须将 i 保留在 preorder 之外,以允许它在调用之间更改

    一个例子是下面的代码:

    int *a = malloc(sizeof(int)*50);
    int inx = 0;
    preorder(bt1, a, &inx);
    
    
    
    void preorder(TreeNode *root, int* a, int* inx) {
        if(root == NULL)
            return;
        else {
            if(root != NULL) {
                a[*inx] = root->val;
                *inx = *inx + 1;
                preorder(root->left, a, inx);
                preorder(root->right, a, inx);
            }
        }
    }
    

    【讨论】:

    • int&amp; inx这不属于C,C++允许这样做。
    • 答案必须是 C 而不是 C++。并且不会将相同的inx 传递给两个递归的preorder 调用导致它们都存储到同一个索引中吗?另外,显示的解决方案中的返回值有什么意义?
    • @kaylum preorder 更改 inx 如果它在数组中存储任何内容。你是对的,它应该是一个void函数
    【解决方案3】:

    在此函数的每次递归调用中,您将分配:

    int *a = malloc(sizeof(int)*50);

    您需要为数组分配一次空间,然后使用同一个数组。使用 i = 0 也是如此。您需要使用一个计数器。

    您可能希望在main 函数中创建数组,然后将数组作为函数参数传递。或者您可以使用全局数组,并以这种方式访问​​它。计数器变量也是如此。

    注意:在您的示例中我看不到内存分配的意义。如果您确定该树不会有更多 ARRAY SIZE 节点,则最好使用静态数组。

    【讨论】:

      猜你喜欢
      • 2022-01-17
      • 1970-01-01
      • 2012-04-06
      • 1970-01-01
      • 2013-04-03
      • 1970-01-01
      • 1970-01-01
      • 2019-02-25
      • 1970-01-01
      相关资源
      最近更新 更多