所以我需要为我的应用程序创建一个基本的二叉树,但即使在生成过程中,我也很难理解如何导航#。
每个节点当然都有一个地址,并指向另外两个分别保持正负值的节点。我的问题是,如果我想使用循环创建树,我该怎么做?在第一次迭代中将有两个节点,第三次将有四个,依此类推 - 如何在推进循环之前遍历每个地址?
for(int i=1;i<=5;i++){
(*currentAddress).value = i;
(*currentAddress).positive = i;
(*currentAddress).negative = i*-1;
//update current address
}
我是否必须在每次迭代时都使用BFS,并且在我创建(2 ^ n-1)个节点之前不断添加节点?
答案 0 :(得分:1)
你真的想要左右指针,对吗?然后你可能想要使用递归。例如(用一些随机语言):
function Node* MakeNode(value, limit) {
Node* node = new Node();
(*node).value = value;
// don't create any more children once we get to the depth limit.
if (value < limit) {
(*node).positive = MakeNode(value + 1);
(*node).negative = MakeNode(value - 1);
}
return node;
}
// create a 5 deep tree
MakeNode(0, 5);
答案 1 :(得分:1)
因此,您希望使用循环创建指定深度的完整二叉树。 那是可能的。但你应该首先考虑@PaulColdrey的答案,因为它更简单。
要迭代地创建二叉树,必须知道它的每个节点都可以使用位向量进行唯一标识:
layer 0: ___________________[0]___________________
| |
layer 1: ________[00]________ ________[10]________
| | | |
layer 2: ___[000]___ ___[100]___ ___[010]___ ___[110]___
| | | | | | | |
layer 3: [0000] [1000] [0100] [1100] [0010] [1010] [0110] [1110]
第N个位置的位告诉从第(N-1)层到第N个时采用了哪个分支(左:0 /右:1)。换句话说,位向量是节点的路径;见上文。
从0到2 K - 1计数就足以获得到第K层节点的所有可能路径。最重要的是,当向上计数时,第N位永远不会从0变为1,直到所有较低有效位从0变为1 - 在这种情况下意味着当前第N层子树已满。
这允许每层仅记住一个当前节点,在父节点更改时重新创建所有子节点。
这是它在C中的表现:
struct NODE {
struct NODE *side[2];
double data;
};
struct NODE *fulltree(int depth) {
struct NODE *curr[16] = {};
int path, layer;
if ((depth >= 0) && (depth < 16)) { /** reject exceedingly large trees **/
curr[0] = (struct NODE*)calloc(1, sizeof(struct NODE));
for (path = 0; path < (1 << depth); ++path)
for (layer = 1; layer <= depth; ++layer)
if (((path ^ (path - 1)) >> (depth - layer)) & 1) {
curr[layer - 1]->side[(path >> (depth - layer)) & 1] =
curr[layer] = (struct NODE*)calloc(1, sizeof(struct NODE));
curr[layer]->data =
((path >> (layer - 1)) & 1)? layer : -layer;
}
}
return curr[0];
}
代码假定目标CPU上的负整数为two`s complement。