我正在尝试为已排序的二叉树编写remove(node cRoot, Object o)
函数。
这是我到目前为止所做的:
private boolean remove(Node cRoot, Object o) {
if (cRoot == null) {
return false;
}
else if (cRoot.item.equals(o)) {
//erase node fix tree
return true;
}
else if (((Comparable)item).compareTo(cRoot.item)<=0){
return remove(cRoot.lChild, o);
}
else {
return remove(cRoot.rChild,o);
}
}
它无法正常工作。要删除节点,您必须修复树以修复孔。该怎么做?
答案 0 :(得分:4)
通常有两种方法可以在树上执行删除:
第一种方法:
删除节点,然后将其替换为任一子节点。然后,通过进行父子交换来求助树,直到再次对树进行排序。
第二种方法:
遍历树以查找属于根*的下一个(最高或最低)值,如果它是叶节点,则将其与根交换,然后修剪要删除的值。如果它是内部节点,则必须以递归方式在该节点上调用remove。重复,直到删除叶节点。
*我的意思是,如果您将BST转换为排序列表,那么您将需要选择根目录左侧或右侧的值作为新根。即最右边子树的最左边的子节点,或左子树的最右边的子节点。
答案 1 :(得分:2)
从排序树中擦除节点的基本伪代码非常简单:
基本上你正在做的是在树上冒泡节点,每次节点中每个节点的子节点的最大值,以便最后你留下一个排序的树,并且只有一个节点在完整的末尾丢失你走的路。
另外 - 请参阅wikipedia on the subject,他们在C中也有一些示例代码。
答案 2 :(得分:1)
在简单的情况3中,您可以使用下一个算法:
if(removed node had left child)
{
place left child instead of removed node;
most_right = most right leaf in the left subtree;
move right child of removed node as right child of most_right;
}
else
{
place right child instead of removed node
}
在更复杂的情况下,您可能需要重新平衡树(请参阅AVL树,http://www.cmcrossroads.com/bradapp/ftp/src/libs/C++/AvlTrees.html以获取C ++示例)
答案 3 :(得分:0)
答案 4 :(得分:0)
我在Habrahabr上找到了这段代码。我刚刚添加了评论。
public void remove (T1 k){
Node<T1,T2> x = root, y = null;
// from while to if(x == null) - searching for key
while(x != null){
int cmp = k.compareTo(x.key);
if(cmp == 0){
break; // quit cycle if key element is found
} else {
y = x;
if(cmp < 0){
x = x.left;
} else {
x = x.right;
}
}
}
if(x == null) return; // if key is not found or tree is empty
if(x.right == null){ // if element found has not right child
if(y == null){ // if element found is root & has not right child
root = x.left;
} else { // if element found is not root & has not right child
if(x == y.left) y.left = x.left;
else y.right = x.left;
}
} else { // element found has right child, so search for most left of rights
Node<T1,T2> mostLeft = x.right;
y = null;
while(mostLeft.left != null) {
y = mostLeft;
mostLeft = mostLeft.left;
}
if(y == null){ // if right child of element found has not left child
x.right = mostLeft.right;
} else { // if right child of element found has left child
y.left = mostLeft.right;
}
x.key = mostLeft.key;
x.value = mostLeft.value;
}
}