Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 红黑树根删除_C#_Algorithm_Data Structures_Binary Tree_Red Black Tree - Fatal编程技术网

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,则过程完全相同,但您将保留左侧而不是右侧

希望这能弄清楚为什么会这样。我不打算告诉你如何解决这个问题,原因有二:

  • 这几乎可以肯定是家庭作业,除非是为了家庭作业,否则没有人会使用红黑树
  • 我不太清楚红黑树的实现细节,主要是因为原因1

  • 祝你好运解决它

    与我一起完成以下步骤:

    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,则过程完全相同,但您将保留左侧而不是右侧

    希望这能弄清楚为什么会这样。我不打算告诉你如何解决这个问题,原因有二:

  • 这几乎可以肯定是家庭作业,除非是为了家庭作业,否则没有人会使用红黑树
  • 我不太清楚红黑树的实现细节,主要是因为原因1

  • 祝你好运解决它

    是的,事实上我弄错了,当我继续调试时,根总是排除要删除的所选节点的正确子树。这不仅发生在根目录中,还可能为需要做的事情提供一点提示吗?我不确定我是否从我的方法中漏掉了很多信息。我对您的代码了解不够,无法帮助您进行广泛的调试,但听起来您与
    sentinel
    的比较不起作用。如果您尚未在
    RedBlackNode
    上定义
    Equals()
    方法,它将测试引用标识上的相等性(我认为),因此除非您在任何地方都使用完全相同的
    sentinel
    ,否则比较可能不起作用。或者是别的,我不知道。你最好(也更安全地)和同学聊天,或者在老师的办公时间拜访老师。这个问题已经解决了。第二天,我调试了它,没有注意到我遗漏了另一个案例,因为左和右的孩子都被填充了。添加了另一个方法findMinimum(),根的值将根据返回的值进行更改。是的,事实上我错了,当我继续调试时,根总是排除要删除的所选节点的正确子树。这不仅发生在根目录中,还可能为需要做的事情提供一点提示吗?我不确定我是否从我的方法中漏掉了很多信息。我对您的代码了解不够,无法帮助您进行广泛的调试,但听起来您与
    sentinel
    的比较不起作用。如果您尚未在
    RedBlackNode
    上定义
    Equals()
    方法,它将测试引用标识上的相等性(我认为),因此除非您在任何地方都使用完全相同的
    sentinel
    ,否则比较可能不起作用。或者是别的,我不知道。你最好(也更安全地)和同学聊天,或者在老师的办公时间拜访老师。这个问题已经解决了。第二天,我调试了它,没有注意到我遗漏了另一个案例,因为左和右的孩子都被填充了。添加了另一个方法findMinimum(),根的值将根据返回的值进行更改。