Tracing add on a Linked Heap
LinkedHeap is a binary min-heap built from nodes, so a smaller value has higher priority. Here is its add. pathTo(position) returns the directions from the root to that position. '0' means left and '1' means right. Positions are numbered in level order, starting from 1 at the root.
public void add(T item) {
size++;
root = add(root, item, pathTo(size), 0);
}
private Node<T> add(Node<T> node, T item, String path, int index) {
if (index == path.length()) {
return new Node<>(item);
}
if (path.charAt(index) == '0') {
node.left = add(node.left, item, path, index + 1);
swimStep(node, node.left);
} else {
node.right = add(node.right, item, path, index + 1);
swimStep(node, node.right);
}
return node;
}
// Swaps the values of parent and child if the child outranks the parent.
private void swimStep(Node<T> parent, Node<T> child) { ... }
The heap holds these six values:
╭────╮
│ 20 │
╰──┬─╯
┌──────────┴──────────┐
╭──┴─╮ ╭──┴─╮
│ 60 │ │ 50 │
╰──┬─╯ ╰──┬─╯
┌────┴────┐ ┌───┘
╭──┴─╮ ╭──┴─╮ ╭──┴─╮
│ 90 │ │ 70 │ │ 80 │
╰────╯ ╰────╯ ╰────╯
Solution
size becomes 7, which is 111 in binary, so the path is 11: right, then right.
The call stack when the base case is reached, top first:
add(node = null) base case: returns a new node holding 40
add(node = 50) waiting for add(50.right)
add(node = 20) waiting for add(20.right)
The call on 50 stores the new node as its right child. 40 outranks 50, so swimStep swaps them:
╭────╮
│ 20 │
╰──┬─╯
┌──────────┴──────────┐
╭──┴─╮ ╭──┴─╮
│ 60 │ │ 40 │
╰──┬─╯ ╰──┬─╯
┌────┴────┐ ┌────┴────┐
╭──┴─╮ ╭──┴─╮ ╭──┴─╮ ╭──┴─╮
│ 90 │ │ 70 │ │ 80 │ │ 50 │
╰────╯ ╰────╯ ╰────╯ ╰────╯
The call on 20 stores the same node as its right child. 40 does not outrank 20, so swimStep does nothing, and the call returns the root. The tree stays as drawn above.