C# 红黑树根删除
我的红黑树删除算法运行良好,除非我删除根。其中仅保存一个子项,其余树值丢失 我相信问题出在C# 红黑树根删除,c#,algorithm,data-structures,binary-tree,red-black-tree,C#,Algorithm,Data Structures,Binary Tree,Red Black Tree,我的红黑树删除算法运行良好,除非我删除根。其中仅保存一个子项,其余树值丢失 我相信问题出在removeNode()方法的以下行中 if (remove == root) { root = child; } 以下是用于删除的方法: //Searching for value to remove public void removeSearch(int value) { RedBlackNode rt = root; while (rt != sentinel)
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();
}
任何帮助都会很好。谢谢请与我一起浏览:
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,则过程完全相同,但您将保留左侧而不是右侧
希望这能弄清楚为什么会这样。我不打算告诉你如何解决这个问题,原因有二:
祝你好运解决它 与我一起完成以下步骤:
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,则过程完全相同,但您将保留左侧而不是右侧
希望这能弄清楚为什么会这样。我不打算告诉你如何解决这个问题,原因有二:
祝你好运解决它 是的,事实上我弄错了,当我继续调试时,根总是排除要删除的所选节点的正确子树。这不仅发生在根目录中,还可能为需要做的事情提供一点提示吗?我不确定我是否从我的方法中漏掉了很多信息。我对您的代码了解不够,无法帮助您进行广泛的调试,但听起来您与
sentinel
的比较不起作用。如果您尚未在RedBlackNode
上定义Equals()
方法,它将测试引用标识上的相等性(我认为),因此除非您在任何地方都使用完全相同的sentinel
,否则比较可能不起作用。或者是别的,我不知道。你最好(也更安全地)和同学聊天,或者在老师的办公时间拜访老师。这个问题已经解决了。第二天,我调试了它,没有注意到我遗漏了另一个案例,因为左和右的孩子都被填充了。添加了另一个方法findMinimum(),根的值将根据返回的值进行更改。是的,事实上我错了,当我继续调试时,根总是排除要删除的所选节点的正确子树。这不仅发生在根目录中,还可能为需要做的事情提供一点提示吗?我不确定我是否从我的方法中漏掉了很多信息。我对您的代码了解不够,无法帮助您进行广泛的调试,但听起来您与sentinel
的比较不起作用。如果您尚未在RedBlackNode
上定义Equals()
方法,它将测试引用标识上的相等性(我认为),因此除非您在任何地方都使用完全相同的sentinel
,否则比较可能不起作用。或者是别的,我不知道。你最好(也更安全地)和同学聊天,或者在老师的办公时间拜访老师。这个问题已经解决了。第二天,我调试了它,没有注意到我遗漏了另一个案例,因为左和右的孩子都被填充了。添加了另一个方法findMinimum(),根的值将根据返回的值进行更改。