c - 使用递归策略将数组转换为二叉树
问题描述
我需要从包含一些零的向量开始创建一个二叉树,其中零表示一个不存在的节点。例如,如果我得到:
int a[] = {10,4,7,2,3,-1,8,9,-1,2,4,5};
我希望我的输出是这样的:
10
/ \
4 7
/ \ \
2 3 8
/ / \ /
9 2 4 5
我的结构:
typedef struct node {
int n;
struct node * dx;
struct node * sx;
} *Bit_node;
构建一个节点的方法:
Bit_node bit_new(int n) {
Bit_node new_node = malloc(sizeof(struct node));
new_node -> n = n;
return new_node;
}
构建整棵树的方法:
Bit_node bit_arr2tree(int a[], int size, int i) {
if (i>= size) {
return NULL;
}
if(a[i] != -1) {
Bit_node new_node = bit_new(a[i]);
new_node -> sx = bit_arr2tree(a, size, i*2 +1);
new_node -> dx = bit_arr2tree(a, size, i*2 +2);
}
return new_node;
}
但是通过我的实现,我的树是在不考虑“漏洞”的情况下构建的。有没有办法考虑它们,保持递归策略?
解决方案
首先,int a[] = {10,4,7,2,3,-1,8,9,-1,2,4,5};
不应该产生您期望的树,5 作为 8 的左孩子。由于 8 在索引 6 处,它的左孩子将在 index 处6 * 2 + 1 == 13
。因此,您的输入可能应该是int a[] = {10,4,7,2,3,-1,8,9,-1,2,4,-1,-1,5};
,在数组末尾有两个额外的 -1 以将 5 推送到正确的索引。
您的实现无法工作,因为在模式中:
{
Bit_node new_node = malloc(...)
}
return new_node;
new_node
不在范围内时正在访问。如果遇到 -1,您希望返回 NULL,就像您在数组越界时所做的一样。返回 NULL 表示“这里没有孩子”,这正是您想要与父框架通信的内容,以便它将丢失的孩子设置为 NULL。
修复应该非常简单:
Bit_node bit_arr2tree(int a[], int size, int i) {
if (i>= size || a[i] < 0) {
// ^^^^^^^^^^^
return NULL;
}
Bit_node new_node = bit_new(a[i]);
new_node->sx = bit_arr2tree(a, size, i * 2 + 1);
new_node->dx = bit_arr2tree(a, size, i * 2 + 2);
return new_node;
}
顺便说一句,我会警告不要将指针类型化。这会降低代码的可读性并隐藏信息。
这是一个可运行的概念证明:
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *left;
struct Node *right;
};
struct Node *arr2tree(int arr_len, int *arr, int i) {
if (i >= arr_len || arr[i] < 0) {
return NULL;
}
struct Node *node = malloc(sizeof(*node));
node->data = arr[i];
node->left = arr2tree(arr_len, arr, i * 2 + 1);
node->right = arr2tree(arr_len, arr, i * 2 + 2);
return node;
}
void print_tree(struct Node *root, int depth) {
if (root) {
print_tree(root->right, depth + 4);
for (int i = 0; i < depth; i++) {
printf(" ");
}
printf("%d\n", root->data);
print_tree(root->left, depth + 4);
}
}
void free_tree(struct Node *root) {
if (root) {
free_tree(root->left);
free_tree(root->right);
free(root);
}
}
int main() {
int a[] = {10,4,7,2,3,-1,8,9,-1,2,4,-1,-1,5};
struct Node *root = arr2tree(sizeof(a) / sizeof(a[0]), a, 0);
print_tree(root, 0);
free_tree(root);
return 0;
}
输出:
8
5
7
10
4
3
2
4
2
9
推荐阅读
- python - 如何从python中的列表中提取单引号数字
- css - 使用元素中未定义的 css 删除字符
- vue.js - 将 Vue.js 迁移到 Angular 6。欢迎提示?
- javascript - 在 ES6 Node.js 中,如何让一个类随处可用?
- kubernetes - 如何使用 kubectl 和 jsonpath 将 configmap 的内容保存到文件中?
- oracle - 查询属于另一个数据库的表名
- tfs - 查询目标日期在 TFS 中更改了多少次
- python - 如果服务之间存在依赖关系,NaoQ 将以什么顺序终止服务?
- java - 如何在另一个方法之后调用该方法?
- javascript - 检查json数据长度是否不起作用