了解二进制搜索树中删除算法的基础,并创建了以下代码以从树中删除最大值。
public void DelLargest()
{
Node<T> del = this;
boolean child = this.left.empty();
boolean child2 = this.right.empty();
right.DelLargest();
if(child && child2)
this.head = null;
else if(child == true && child2 == false)
this.head = left;
}
基本上我所拥有的是递归运行直到&#39;这个&#39;是最右边的节点,然后检查两种情况,是否&#39;这&#39;是一片叶子,还是这个&#39;有一个左孩子。 (通常与这种算法相关的另一种情况是冗余的,因为在找到具有最大值的节点时,我已经尽可能地去了。)我遇到的麻烦是让当前节点然后指向null或者在Node左边的值。
注意:这就是我的导师所说的现代&#34;二进制搜索树,其中一个顶点或&#34;填充&#34;节点和nil或&#34;空&#34; node是Interface Node的两个子类,它定义了每种类型的特征。
我设法将问题缩小到我没有返回给定节点值的方法这一事实。现在正在努力,投入将不胜感激。
答案 0 :(得分:0)
你有正确的想法。你想要做的是保持对最右边节点父节点的引用,并且最右边的节点保留为子节点,这样当你删除它时,你可以附加两个节点。
这是一个迭代解决方案。这通常比递归更有效,但如果你想要递归,你应该能够适应它:
public void delLargest() {
// get rightmost node's parent
Node<T> current = root;
while(current.right != null && current.right.right != null) {
current = current.right;
}
// get the rightmost nodes left node
Node<T> left = current.right.left;
// attach the parent and left
current.right = left;
// nothing points to the right most node anymore, so it will be garbage collected
}
答案 1 :(得分:0)
正如其他答案中所建议的那样,你应该使用迭代方法。
在BST中,最大值是最右边的节点。 所以进行扫描并继续向右直到你达到空值。 在扫描中跟踪三个节点。 (gpnode,pnode,node)。 扫描完成后,您将拥有(gpnode,pnode,null) 现在有2个案例。
案例1:
pnode
是一片叶子。因此,请将边(gpnode,pnode)
更改为(gpnode,null)
案例2 :( 已编辑)
pnode.lChild
不为空。请注意,pnode.rChild
将为null,因为搜索将在该点终止。
现在将边缘(gpnode,pnode)
更改为(gpnode,pnode.lChild)
这是伪代码:
public class Node
{
long key;
Node lChild;
Node rChild;
}
public void DelLargest()
{
Node gpnode = null;
Node pnode = null;
Node node = root;
while(node != null) // keep going right until a null is reached
{
gpnode = pnode;
pnode = node;
node = node.rChild;
}
if(pnode.lChild == null) // its a leaf node So change the edge (gpnode,pnode) to (gpnode,null)
{
if(gpnode.lChild == pnode)
{
gpnode.lChild = null;
}
else
{
gpnode.rChild = null;
}
}
else // copy lChild's key to this node and delete lChild
{
if(gpnode.lChild == pnode)
{
gpnode.lChild = pnode.lChild;
}
else
{
gpnode.rChild = pnode.lChild;
}
}
}