红黑树删除根

时间:2016-04-12 22:12:23

标签: c# algorithm data-structures binary-tree red-black-tree

我的红黑树算法删除效果很好,除非我删除根。只有一个孩子得救,其余的树值丢失。

我认为问题出在<{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();
}

任何帮助都会很棒。感谢

1 个答案:

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

希望这应该清除它为什么会发生。我不会告诉你如何解决它有两个原因:

  1. 这几乎可以肯定是家庭作业,除非是家庭作业,否则没有人会实施红黑树。
  2. 我不太清楚红黑树的实施细节,主要原因是1号原因。
  3. 祝你好运解决它!