红黑树 - 如果root是祖父母,如何旋转?

时间:2010-07-26 23:42:52

标签: java rotation red-black-tree

我正在自己写红黑树。但是当我测试涉及根旋转的旋转时,它会失去参考。

树形结构:

          45             
        /    \
      40x      70        
     /  \     /
    7   41   50           
   / \
  6  39

旋转逻辑说: “以45(根)作为顶部旋转,朝向提升X的方向(即40)”

所以这意味着正确旋转,结果应如下所示:

     40x  
    /   \
   7     45
 / \     / \
 6  39  41  70
           /
          50

假设节点45是祖父母,7是父母,41是当前。 (我知道顺序没有意义,但请忽略,这是因为我已经旋转了一次)

代码:

  //current is node 45
    //parent is node 7
    //grandparent is node 45 (root)

    //first detach cross node (i.e. 41)
    Node crossNode2 = grandparent.left.right;
    grandparent.left.right = null; //detach


                   45             
                /     \
              40x      70        
             /  \      /
            7   null   50           
           / \
          6  39

    grandparent.left = null;




                   45             
                 /    \
               null   70        
                      /
                    50           

    current.right = grandparent;

          40
        /    \
      7        45
     /  \     /  \
   6    39   null 70
                  /
                 50

    grandparent.left = crossNode2; //attach


         40  
        /   \
       7     45
     / \     / \
     6  39  41  70
               /
              50

但不知何故,这段代码不起作用。当我测试时:

preorder
45, 39, 70, 50
breadth-first
45, 39, 70, 50

所以我认为结果实际上是:

  45
 /  \
39  70
     /
    50

有人能给我提示我的轮换代码有什么问题吗?

2 个答案:

答案 0 :(得分:3)

在节点Q上执行右旋转的步骤:

  1. 让P = Q的左孩子。
  2. Q的左孩子= P的右孩子
  3. P将Q替换为其父母的孩子
  4. P的右孩= Q
  5. 您错过了所提供代码中的粗体步骤。我认为你的问题是你正在将涉及根节点的轮换视为一种特殊情况。显然,如果Q是根且其父级为null,则无法执行此操作。尝试创建一个“头”节点,谁是正确的节点是根。这允许涉及根的旋转使用常规算法工作。

    public static void rotateRight(Node node) {
        assert(!node.isLeaf() && !node.left.isLeaf());
        final Node child = node.left;
        node.setLeft(child.right);
        if (node.isRightChild())
             node.parent.setRight(child);
        else node.parent.setLeft(child);
        child.setRight(node);
    }
    

    setRightsetLeft保持parent参考更新以及更新rightleft的节点。 node.isRightNode()来电可以只是(node.parent.right == node)

答案 1 :(得分:0)

根据Gunslinger47的回答,我也测试了左旋转版本。 代码工作正常。 (如果没有,请告诉我。)

还在我的网站上记录:)

http://masatosan.com/btree.jsp

public static void rotateLeft(Node node) {
    assert(!node.isLeaf() && !node.right != null);
    final Node child = node.right;
    node.setRight(child.left);
    if(node.isLeftChild()) {
        node.parent.setLeft(child);
    }
    else {
        node.parent.setRight(child);
    }
    chlid.setLeft(node);
}