当前位置: 首页 > 知识库问答 >
问题:

为什么我无法从下面的代码中获得二叉树级别的顺序遍历?

杨君之
2023-03-14

我正在尝试对二叉搜索树进行一次级别顺序遍历,并在多维数组中返回最终结果。例如,如果根节点是2,而级别1的节点是1,4,那么它应该从代码返回[[2],[1,4]]作为returnColumnSizes。我是数据结构方面的新手,也没有使用malloc函数的命令。任何帮助都将不胜感激。谢谢:)

int height(struct TreeNode *h){
    if (h == NULL) return 0;
    int l = height(h->left);
    int r = height(h->right);
    if (l > r)
        return l+1;
    else
        return r+1;
}

int *ordercalc(struct TreeNode *root, int level){
    if (root == NULL) return NULL;
    int i = 0, arr[100];
    if (level == 1)
        arr[i++] = root->val;
    else if(level > 1){
        ordercalc(root->left, level-1);  //decrease the level one per call to print data when it
        ordercalc(root->right, level-1);  // reaches proper level
    }
    return arr;
}

int** levelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes){
    if (*returnSize == 0) return NULL;
    **returnColumnSizes = (int **)malloc(*returnSize * sizeof(int *));
    for (int i=0;i<height(root)+1;i++){
        returnColumnSizes[i] = (int *)malloc(sizeof(int) * 10);
        returnColumnSizes[i] = ordercalc(root, i);
    }
    return returnColumnSizes;
}

共有1个答案

慕容坚
2023-03-14

高度看起来不错。

levelOrder看起来不错,不过i

ordercalc需要重新考虑。函数在其堆栈框架上分配了arr[100];

if (level == 1)
    arr[i++] = root->val;

return arr;

我可以看到你试图根据高度来填充水平,这是正确的想法。然而:

  1. 返回堆栈分配的数组是未定义的行为。当调用返回时,无法访问其帧上的所有数据。如果要执行此操作,需要在堆上malloc,并返回一个指针

与此函数返回结果不同,传入指向预分配结果结构的指针似乎是最简单的。

简化重新分配和大小管理的一种方法是使用多个过程来处理问题。以下是游戏计划:

  1. 获取树的高度

这是代码:

int height(struct TreeNode *root) {
    if (root) {
        int left = height(root->left);
        int right = height(root->right);
        return 1 + (left > right ? left : right);
    }

    return 0;
}

void set_col_lens(struct TreeNode *root, int *res_col_lens, int depth) {
    if (root) {
        res_col_lens[depth]++;
        set_col_lens(root->left, res_col_lens, depth + 1);
        set_col_lens(root->right, res_col_lens, depth + 1);
    }
}

void fill_levels(struct TreeNode *root, int **res, int *last_items, int level) {
    if (root) {
        int last_item = last_items[level]++;
        res[level][last_item] = root->val;
        fill_levels(root->left, res, last_items, level + 1);
        fill_levels(root->right, res, last_items, level + 1);
    }
}

int **level_order(struct TreeNode *root, int *res_len, int **res_col_lens) {
    if (!root) {
        *res_len = 0;
        return NULL;
    }

    *res_len = height(root);
    int **res = malloc(sizeof(*res) * (*res_len));
    *res_col_lens = calloc(*res_len, sizeof(**res_col_lens));
    int *last_items = calloc(*res_len, sizeof(*last_items));
    set_col_lens(root, *res_col_lens, 0);

    for (int i = 0; i < *res_len; i++) {
        res[i] = malloc(sizeof((*res)[i]) * (*res_col_lens)[i]);
    }

    fill_levels(root, res, last_items, 0);
    free(last_items);
    return res;
}

这样做的一个好处是,问题被分成简单、不同的步骤。

我认为更自然的另一种方法是使用队列并在一个堆栈帧中执行广度优先遍历。然后,问题变成了用C编写队列抽象,这并不难,但确实需要一点大惊小怪。

 类似资料:
  • 我正在尝试对二叉树进行级别顺序遍历。但诀窍是代替正常的级别顺序遍历,我想做另一种选择。对于例如。 普通等级顺序遍历 : 我要找的是我们打印根。现在,对于每一个偶数级,我都想逆时针旋转,对于每奇数级,都会顺时针旋转: 对于这种遍历,输出应该是: 这是我到目前为止尝试的,但这产生的输出与我试图实现的输出略有不同: 该程序产生以下输出: < code>1 3 2 5 4 7 6 10 11 9 8 我需

  • 我正在研究爪哇的树木,在我正在研究的书中偶然发现了一些令人困惑的台词。给出的顺序遍历图如下: 遍历(递归)的代码是: 我感到困惑的是: 我已经突出了我所困住的部分。首先,我认为在第三步中,inOrder(C)[而不是inOrder(B)]返回inOrder(A)。第二,访问节点的顺序应该是B->A->C。 请帮帮我吧!

  • 我想对二叉树执行级别顺序遍历。因此,对于给定的树,说: 产出将是: 我知道我可以使用某种队列,但在C中递归地实现这一点的算法是什么?感谢您的帮助。

  • 我尝试按如下方式执行二叉树的垂直顺序遍历:1)找出每个节点与根节点之间的最小和最大水平距离2)创建一个hashmap,将水平距离映射到相应的节点(Map) 然而,我得到了不想要的输出,我认为在实现中有一些错误,因为算法对我来说似乎是正确的。 以下是完整的代码: 输出:{-1=[99999],0=[99999,12],-2=[99999],1=[99999],2=[99999]}那么我的apProc

  • 这是一个相当简单的问题,我注意到当我表示一棵树时,无论我用哪种方式(后排序,按顺序,前排序)树叶总是以相同的顺序出现,从左到右。 我只是想知道为什么,这是有原因的吗? 我刚开始研究它们,就想到了这个。 编辑: 我有一棵这样的树: 叶节点为:D、E和F 预购顺序为:A、B、D、C、E、F 顺序是:D,B,A,E,C,F 后序是:D,B,E,F,C,A 叶子节点总是从左到右出现,不管我选择哪个顺序,问

  • 为了上课,我必须创建一个状态对象的二叉树,每个状态对象包括一个居民对象的二叉树,这些居民对象组织住在每个州的人。我试图在一个给定的州中搜索最老的居民;然而,居民是按字母顺序组织在树中的,这对我的搜索毫无帮助。因此,我必须遍历整个居民树,更新保存最老的人的节点,并在树被完全遍历后返回它。我已经有了代码的第一部分,但是还停留在如何写递归的剩余部分。 状态树的方法: 然后是公共“包装器”状态树方法: