Computing Library › Classical Algorithms
Classical Algorithms

Persistent Data Structures

Structures that preserve every previous version after an update, allowing queries against any point in their history.

Versions that never die

A persistent data structure keeps all its past versions accessible after modifications. Partial persistence allows queries on any version but updates only on the latest; full persistence allows updates on any version, branching history into a tree; confluent persistence even allows merging versions. Persistence is achieved without copying the whole structure on each change.

Path copying

Kronos motion — operating point

The standard technique for tree-shaped structures is path copying: an update creates new copies only of the nodes on the path from the root to the change, sharing all untouched subtrees with the previous version. A new root points to the new path. Each update costs O(log n) extra nodes for a balanced tree, and every old root still describes a valid past version.

Persistent segment-tree update

python
def update(node, lo, hi, i, val):
    if lo == hi:
        return Node(val)                 # new leaf
    mid = (lo + hi) // 2
    if i <= mid:
        return Node(left=update(node.left, lo, mid, i, val),
                    right=node.right)     # share right subtree
    else:
        return Node(left=node.left,
                    right=update(node.right, mid+1, hi, i, val))

What it powers

Cost model

Path copying keeps each update's extra space proportional to the modified path length, so k updates on an n-node tree use O(k log n) total space while preserving all k+1 versions, an application of the sharing that makes immutable structures practical.