3

我正在自己写红黑树。但是当我测试涉及要旋转的根的旋转时,它在某种程度上失去了参考。

树结构:

          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

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

4

2 回答 2

3

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

  1. 令 P = Q 的左孩子。
  2. Q 的左孩子 = P 的右孩子
  3. P 代替 Q 作为其父母的孩子
  4. P的右孩子= Q

您在提供的代码中缺少粗体步骤。我认为您的问题是您将涉及根节点的旋转视为特殊情况。显然,如果 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)只是。

于 2010-07-27T03:24:30.520 回答
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);
}
于 2010-07-27T18:40:45.277 回答