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

发布于 2024-09-11 16:22:40 字数 1633 浏览 4 评论 0原文

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

树结构:

          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

任何人都可以给我提示我的轮换代码有什么问题吗?

I am working on writing red-black tree myself. But when I test the rotation that involves root to be rotated, somewhat it loses reference.

Tree structure:

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

The rotate logic says:
"Rotate with 45(root) as top, in the direction that raises X (i.e. 40)"

So this means right rotate and result should look like:

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

Assuming that node 45 is grandparent and 7 is parent and 41 is current. (I know the order doesn't make sense but please ignore, this is because I've rotated once already)

Code:

  //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

But somehow this code does not work. When I tested:

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

So I think the result is actually:

  45
 /  \
39  70
     /
    50

Could anyone give me tips what's wrong with my rotation code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

魂ガ小子 2024-09-18 16:22:40

对节点 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)

Step to do a right rotation on node Q:

  1. Let P = Q's left child.
  2. Q's left child = P's right child
  3. P replaces Q as its parent's child
  4. P's right child = Q

You're missing the bolded step in your supplied code. I think your problem is you're treating rotations involving the root node as a special case. Obviously you can't do this if Q is the root and its parent is null. Try creating a "head" node who's right node is the root. This allows rotations involving the root to work using normal algorithms.

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);
}

Node that setRight and setLeft keep the parent reference updated as well as updating right and left. The node.isRightNode() call can be just (node.parent.right == node).

醉酒的小男人 2024-09-18 16:22:40

根据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);
}

Based on Gunslinger47's answer, I've tested left rotation version too.
The code works fine. (please do let me know if not..)

Also documented on my website :)

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文