我的红黑树算法删除效果很好,除非我删除根。只有一个孩子得救,其余的树值丢失。
我认为问题出在<{p>行中的removeNode()
方法中
if (remove == root)
{
root = child;
}
以下是用于删除的方法:
//Searching for value to remove
public void removeSearch(int value)
{
RedBlackNode rt = root;
while (rt != sentinel)
{
int compare = value.CompareTo(rt.getItem());
if (compare == 0)
{
if (rt.getLeft() == sentinel || rt.getRight() == sentinel)
{
removeNode(rt);
}
else
{
RedBlackNode successor = inOrderSuccessor(rt);
rt.setItem(successor.getItem());
removeNode(rt);
}
return;
}
else
{
rt = rt.getChild(compare);
//return true;
}
}
}
protected RedBlackNode inOrderSuccessor(RedBlackNode node)
{
RedBlackNode descendant = node.getRight();
while (descendant.getLeft() != sentinel)
{
descendant = descendant.getLeft();
}
return descendant;
}
protected void removeNode(RedBlackNode remove)
{
count -= 1;
RedBlackNode child;
if (remove.getLeft() != sentinel)
{
child = remove.getLeft();
}
else
{
child = remove.getRight();
}
linkParentAndChild(remove.getParent(), child, comparison(remove, remove.getParent()));
if(remove==root)
{
root = child;
}
if(remove.isBlack())
{
DeleteFix(child);
}
}
protected void DeleteFix(RedBlackNode node)
{
while((node!=root)&&(node.isBlack()))
{
RedBlackNode parent = node.getParent();
int compare = comparison(node, parent);
RedBlackNode sibling = parent.getChild(-compare);
if(sibling.isRed())
{
sibling.setBlack();
parent.setRed();
rotate(-compare, parent);
sibling = node.getParent().getChild(-compare);
}
if(sibling.hasTwoBlackChildren())
{
sibling.setRed();
node = node.getParent();
}else
{
if(sibling.getChild(-compare).isBlack())
{
sibling.getChild(compare).setBlack();
sibling.setRed();
rotate(compare, sibling);
sibling = parent.getChild(-compare);
}
sibling.setColour(parent.getColour());
parent.setBlack();
sibling.getChild(-compare).setBlack();
rotate(-compare, parent);
node = root;
}
}
node.setBlack();
}
任何帮助都会很棒。感谢
答案 0 :(得分:0)
跟我一起走过这个:
if (remove.getLeft() != sentinel)
{
child = remove.getLeft();
}
else
{
child = remove.getRight();
}
linkParentAndChild(remove.getParent(), child, comparison(remove, remove.getParent()));
if(remove==root)
{
root = child;
}
首先,假设remove == root
。然后,假设根的左边孩子是sentinel
。第一个if分支求值为false,执行else
子句,child
成为正确的节点。然后,你试图获得根的父级(大概null
,但我不知道)并将其链接到正确的节点...我想这最终什么都不做,但我不知道当然,因为你没有提供这种方法。然后,用child
替换根,这是正确的节点,因为linkParentAndChild
(可能)在null
中传递,所以无法恢复左节点,所以你破坏了它已经消失了。如果左侧节点不是sentinel
,那么过程完全相同,但您将保留左侧而不是右侧。
希望这应该清除它为什么会发生。我不会告诉你如何解决它有两个原因:
祝你好运解决它!