Reputation: 19071
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?
Upvotes: 3
Views: 2570
Reputation: 19071
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);
}
Upvotes: 0
Reputation: 7061
Step to do a right rotation on node 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)
.
Upvotes: 4