在Java中,如何将节点插入到完整的二叉树中?
我们都知道,当插入到一个完整的二叉树中时,我们必须从左到右填充所有叶的所有子树。我使用以下方法将节点插入到完整的二叉树中在Java中,如何将节点插入到完整的二叉树中?,java,data-structures,binary-tree,Java,Data Structures,Binary Tree,我们都知道,当插入到一个完整的二叉树中时,我们必须从左到右填充所有叶的所有子树。我使用以下方法将节点插入到完整的二叉树中 //fields private T item; private int size; private CBTree<T> left, right; //add method public void add(T item) { if(left == null) { left = new CBTree<T>(item);
//fields
private T item;
private int size;
private CBTree<T> left, right;
//add method
public void add(T item)
{
if(left == null)
{
left = new CBTree<T>(item);
size += left.size;
}
else if(right == null)
{
right = new CBTree<T>(item);
size += right.size;
}
else if(!((left.left != null) && (left.right != null)) &&
((right.left == null) || (right.right == null)))
{
left.add(item);
}
else
{
right.add(item);
}
}
因此,它将根更改为2。有没有办法将根更改回其原始值?我试图在不使用堆栈和队列的情况下实现这一点。仅仅检查孩子们的孩子们来确定去哪一边是不够的,因为一旦树达到4号高度,这将不再有效,因为根之子的子从那个点开始不会改变,我们仍然可以向左或向右 我想到了两种方法:
complete
变量
没有子节点的节点已完成
具有两个大小相同的完整子节点的节点已完成
每当更新树(插入或删除)时,也会为每个受影响的节点更新此变量2^n-1
的树已完成(对于某些n
)
注意:只有当我们不允许在不保持树完整的情况下自由删除元素时,这才有效left.add(item)
):
- 左子树不完整
- 左子树和右子树的大小相同(都是完整的,这意味着我们通过插入增加了高度)
注意:在执行
left时,您还需要更新大小。添加(项目)代码>和<代码>右侧。添加(项目)代码>。您可能只需在add
函数中粘贴一个size++
,因为我们添加了1个元素,因此大小无论如何都会增加1。仅检查子元素的子元素以确定要转到哪一侧是不够的,因为一旦树达到高度4,这将不再起作用,因为根之子的子从那个点开始不会改变,我们仍然可以向左或向右
我想到了两种方法:
在每个节点上都有一个complete
变量
没有子节点的节点已完成
具有两个大小相同的完整子节点的节点已完成
每当更新树(插入或删除)时,也会为每个受影响的节点更新此变量
根据大小从数学上确定子树是否完整
大小为2^n-1
的树已完成(对于某些n
)
注意:只有当我们不允许在不保持树完整的情况下自由删除元素时,这才有效
对于任何一种方法,在执行插入时,如果以下任一条件为真,我们将向左(left.add(item)
):
- 左子树不完整
- 左子树和右子树的大小相同(都是完整的,这意味着我们通过插入增加了高度)
我将把实施细节留给你
注意:在执行left时,您还需要更新大小。添加(项目)代码>和<代码>右侧。添加(项目)代码>。您可能只需在add
函数中粘贴size++
,因为我们添加了1个元素,因此大小无论如何都会增加1。多亏了Dukeling的回答,实现该方法的正确方法是从数学上确定子树是否已满。代码如下:
//fields
private T item;
private int size;
private CBTree<T> left, right;
//add method
public void add(T item)
{
if(left == null)
{
left = new CBTree<T>(item);
}
else if(right == null)
{
right = new CBTree<T>(item);
}
else if(leftFull())
{
right.add(item);
}
else
{
left.add(item);
}
size++;
}
//Checks if the left subtree is full
public boolean leftFull()
{
int used, leafs = 1;
while(leafs <= size + 1)
{
leafs *= 2;
}
leafs /= 2;
used = (size + 1) % leafs;
if(used >= (leafs / 2))
{
return true;
}
else
{
return false;
}
}
//字段
私人物品;
私有整数大小;
私人CBTree左、右;
//添加方法
公共作废新增(T项)
{
if(left==null)
{
左=新的CBTree(项目);
}
else if(right==null)
{
右=新的CBTree(项目);
}
else if(leftFull())
{
对。添加(项目);
}
其他的
{
左。添加(项目);
}
大小++;
}
//检查左子树是否已满
公共布尔leftFull()
{
使用int,leafs=1;
while(leafs=(leafs/2))
{
返回true;
}
其他的
{
返回false;
}
}
多亏了杜克林的回答,实现该方法的正确方法是从数学上确定子树是否已满。代码如下:
//fields
private T item;
private int size;
private CBTree<T> left, right;
//add method
public void add(T item)
{
if(left == null)
{
left = new CBTree<T>(item);
}
else if(right == null)
{
right = new CBTree<T>(item);
}
else if(leftFull())
{
right.add(item);
}
else
{
left.add(item);
}
size++;
}
//Checks if the left subtree is full
public boolean leftFull()
{
int used, leafs = 1;
while(leafs <= size + 1)
{
leafs *= 2;
}
leafs /= 2;
used = (size + 1) % leafs;
if(used >= (leafs / 2))
{
return true;
}
else
{
return false;
}
}
//字段
私人物品;
私有整数大小;
私人CBTree左、右;
//添加方法
公共作废新增(T项)
{
if(left==null)
{
左=新的CBTree(项目);
}
else if(right==null)
{
右=新的CBTree(项目);
}
else if(leftFull())
{
对。添加(项目);
}
其他的
{
左。添加(项目);
}
大小++;
}
//检查左子树是否已满
公共布尔leftFull()
{
使用int,leafs=1;
while(leafs=(leafs/2))
{
返回true;
}
其他的
{
返回false;
}
}
是否可能重复@JimMischel我的问题与您链接的问题不同。他们的解决方案似乎和我的一样失败了。多亏了杜克林,我已经找到了实现该方法的正确方法。我将在一点后发布解决方案。可能重复吗@JimMischel我的问题与您链接的问题不同。他们的解决方案似乎和我的一样失败了。多亏了杜克林,我已经找到了实现该方法的正确方法。我将在稍后发布解决方案。更糟糕的是:SO用户回来说“没关系,我想出来了”而不接受答案,或者SO用户说你给了他们正确的答案,但他们自己做了回答?更糟糕的是:SO用户回来说“没关系,我想出来了”而不接受答案,或者让SO用户说你给了他们正确的答案,但作为回报,他们自己回答?如果其他用户帮助显示问题,那么你为什么不接受他的答案?如果其他用户