Algorithms/Left rotation

Treap Example: enforce the invariants:

Binary Heap : Priority Parent > Priory Children Binary Tree : Left child < node < right child

Operation * : rotation ( left )

for a Node to be left rotated ( marked * in example below) caller code: ...  Node = rotate_left(Node) ...

function rotate_left(Node): tmp = Node->right Node->right = tmp ->left tmp -> left = Node Node = tmp return Node

Example: Initially, this is a valid binary tree, but not a valid binary heap.

Insert Xenophon(Priority=56) into tree with root Sally(Priority=66)

Sally | 66 /       \    Harry| 33     Ted | 44 /              \                    Victor | 33 \                        William | 22

-- Step 1: do a usual binary tree insert into a empty leaf.

Sally | 66 /       \    Harry| 33     Ted | 44 /              \                    Victor | 33 \                        William | 22 \                            Xenophon | 56 (a)/

In-order traversal : visit left tree, visit node, visit right subtree

H S T V W X Now the heap invariant has to be established, starting with the recently inserted node.

If there is a pointer between child node to parent, then

while parent priority < node priority: if right child of parent, do left rotate at parent else /* left child of parent */ do right rotate at parent

Otherwise, a post insertion check is done

treap_insert( node, current): if (current = null) return node if ( node.key < current.key) current.left = treap_insert( node, current.left) else current.right = treap_insert( node, current.right)

if current.left != null and current.left.priority > current.priority and ( current.right == null or                                  current.right.priority < current.left.priority ) then current = right_rotate(current) else if current.right != null and current.right.priority > current.priority current = left_rotate(current) return current

NB move by rotating, instead of  exchanging parent and node, as in normal binary heap.

Sally | 66 /         \    Harry| 33      Ted | 44 /              \                    Victor | 33 \                     Xenophon | 56 /                  William | 22 \                            (a)

William is parent and is left rotated with Xenonphon. Xenophon was Williams right child, now becomes parent and William is left child, whereas Xenophon's left child (a) is now William's right child (a).

In-order traversal H S T V W X

Sally | 66 /       \  Harry|33    Ted | 44 /             \                    Xenophon | 56 /              Victor | 33 \               William | 22 \ (a)

Victor is left rotated with Xenophon

In-order traversal is still H S T V W X

Sally | 66 /             \    Harry| 33          Xenophon | 56 /              /                  Ted | 44 \                  Victor | 33 \                    William | 22

Ted is left rotated with Xenophon, Victor, X's left child becomes T's right child, which was formerly X, and T becomes X's new left child.

In-order traversal H S T V W X

Xenophon does not have greater priority than parent (Sally) so while loop exits.

Although this example doesn't look perfectly balanced, when a treap is used to randomly rotate the tree at each insertion, overall, the greater number of trees inserts will produce a well-balanced tree, as compared to a normal binary tree produced from say a non-decreasing ordered sequence of key inserts ( which looks like a linked list ).