假设我有一个最小堆的数据结构:
struct node{
int height;
struct node *parent;
struct node *left;
struct node *right;
};
我想要做的是将一个新节点添加到下一个可用位置(此时保持最小堆属性无关紧要。)到目前为止,我所拥有的是一个空树(根被实例化)早期在代码中早于NULL)。在根已经存在的情况下,我无法弄清楚逻辑。我需要逐个添加元素。我理解如何使用堆作为数组来执行此操作,但我需要使用堆作为二叉树来执行此操作。
void insert(int number)
{
struct node *nodeToInsert;
nodeToInsert=(struct node*)malloc(sizeof(struct node));
nodeToInsert->value = number;
if(root == NULL)
{
root = nodeToInsert;
root->left = NULL;
root->right = NULL;
}
}
答案 0 :(得分:1)
如果我理解正确,您想知道如何下载完整的二叉树以插入下一个节点。您只需要知道底层中已有多少节点。这个数字的位告诉您在向下移动树到下一个可用位置时如何转动(向左或向右)。不幸的是,您可以从树中的项目总数中获取底层的节点数,这通常是您想要跟踪的。
// Let n be the current number of nodes in the tree.
// Subtract sizes of levels until we're at the last.
for (ls = 1, n_levels = 0; ; ls *= 2, n_levels++) {
if (n - ls < 0) break;
n -= ls;
}
// n now contains number of nodes in bottom level
// n_levels contains the number of complete levels above.
struct node *p = root;
for (bit = 1 << (n_levels - 1); bit != 1; bit >>= 1)
if (n & bit)
p = p->right;
else
p = p->left;
if (n & 1)
p->right = new_node();
else
p->left = new_node();
例如说n = 10.所以我们有一个完美的7个节点树,加上3个最低,不完整的层次。第一个循环减去1,2,然后减去4,所以n = 3 = 011_2且n_levels = 3结束。因此,第二个循环产生位掩码1&lt;&lt;&lt; 2 = 4 = 100_2。因此,循环向下移动树,p = p->left
为n的高阶位0,然后是p = p->right
为1.最后一位为1,因此它将新节点置于{{1} }。这是正确的位置(11),如下图所示:
p->right
注意上面的伪代码不处理n = 0的情况,但是你的代码已经这样做了。
答案 1 :(得分:0)
Oof,这并不容易。您基本上需要计算每个非完整节点的深度,并以最小深度插入最左边的节点下。
如果你知道树中有多少个节点,那就容易多了。完成后,您可以直接向下移动到n+1
位置并将节点放在那里。
答案 2 :(得分:0)
有很多方法可以解决这个问题。一种可能的解决方案是使用队列。
这是一个在 python 中的示例实现:
def insert(self,node):
if self.root is None:
self.root = node
return node
else:
q = Queue()
x = self.root
while x is not None:
if x.left is None:
x.left = node
return node
elif x.right is None:
x.right = node
return node
else:
q.add(x.left)
q.add(x.right)
x = q.remove()