AlgoVerse

AVL tree (insert)

A binary search tree that, after each insert, keeps the heights of every node's two subtrees within 1 of each other using one or two rotations.

A plain binary search tree can become a chain (height n). An AVL tree (Adelson-Velsky and Landis, 1962) requires that at every node the heights of the two subtrees differ by at most 1; so the height is always O(log n).

Read the full explanation ↓
Input:
n=0 · insert 10, insert 20, insert 30, insert 40, insert 50, insert 25PDF export

Insert 10, 20, 30, 40, 50, 25; both single and double rotations show up.

  1. class Node:
  2. def __init__(self, key):
  3. self.key = key
  4. self.left = None
  5. self.right = None
  6. self.height = 1
  7. def avl(root, ops):
  8. for op, key in ops:
  9. root = insert(root, key)
  10. return root
  11. def height(node):
  12. if node is None:
  13. return 0
  14. return node.height
  15. def insert(node, key):
  16. if node is None:
  17. return Node(key)
  18. if key < node.key:
  19. node.left = insert(node.left, key)
  20. else:
  21. node.right = insert(node.right, key)
  22. node.height = 1 + max(height(node.left), height(node.right))
  23. balance = height(node.left) - height(node.right)
  24. if balance > 1:
  25. if key > node.left.key:
  26. node.left = rotate_left(node.left)
  27. return rotate_right(node)
  28. if balance < -1:
  29. if key < node.right.key:
  30. node.right = rotate_right(node.right)
  31. return rotate_left(node)
  32. return node
  33. def rotate_right(y):
  34. x = y.left
  35. y.left = x.right
  36. x.right = y
  37. y.height = 1 + max(height(y.left), height(y.right))
  38. x.height = 1 + max(height(x.left), height(x.right))
  39. return x
  40. def rotate_left(x):
  41. y = x.right
  42. x.right = y.left
  43. y.left = x
  44. x.height = 1 + max(height(x.left), height(x.right))
  45. y.height = 1 + max(height(y.left), height(y.right))
  46. return y

Invariant: After every finished insert, each node has |left height − right height| ≤ 1, so the tree's height is O(log n).

Start

∅

Recursion tree

Filled orange = running call · Orange outline = still on the stack · Grey = finished

Local variables

rootNone

Orange = changed in this step

ops list

('insert', 10)('insert', 20)('insert', 30)('insert', 40)('insert', 50)('insert', 25)

Call stack

  1. avl()line 9
Step 1 of 374
Black = inserted · Orange = key stepcompare: 0/11 · create: 0/6 · inserted: 0/6 · balance: 0/11 · rotate_left: 0/3 · rotate_right: 0/1 · right_left: 0/1

    How the work grows with input size

    Average of 8 random graphs per n (fixed seeds). Hollow marker = the input on screen.

    • comparisons
    • rotate_left
    • rotate_right
    • current input (n=6)
    02040603579111315n = number of keyscomparisonsrotate_leftrotate_right
    Show as a table
    ncomparisonsrotate_leftrotate_right
    32.80.30.6
    570.80.8
    712.91.62
    919.12.51.8
    11252.11.9
    13343.94.5
    1542.54.54.5
    Explanation

    The idea

    A plain binary search tree can become a chain (height n). An AVL tree (Adelson-Velsky and Landis, 1962) requires that at every node the heights of the two subtrees differ by at most 1; so the height is always O(log n).

    Insert

    1. Insert as in a plain tree.
    2. On the way back up to the root, update each node's height and compute its balance (left height − right height).
    3. If the balance becomes 2 or −2, fix it with rotations:
      • left–left or right–right: one single rotation.
      • left–right or right–left: two rotations (first on the child, then on the node itself).

    A rotation does not change the order of the keys (the inorder sequence), only the shape of the tree.

    What to watch in the trace

    • After each insert, the balance of the nodes on the way back up is computed; each node's height is in the memory panel.
    • Compare "sorted keys" with the same input in the plain binary search tree algorithm.