Search for a key in a Patricia trie using bitwise branching with path compression.
Patricia trie search operates on a compressed binary trie where branching occurs only at bit positions that distinguish keys.
Instead of storing one level per bit, Patricia tries skip over uniform bit segments. Each node stores the bit index used for branching.
This structure is common for fixed width integer keys, IP routing, and compact prefix sets.
Problem
Given a Patricia trie root and a key x, determine whether x exists in the trie.
Return true if present, otherwise false.
Structure
Each node contains:
| field | meaning |
|---|---|
key | stored key (at leaves or representative nodes) |
bit_index | bit position used for branching |
left | child when bit is 0 |
right | child when bit is 1 |
The tree is organized so that each node compares a specific bit of the key.
Algorithm
Start at the root and follow bit decisions. Stop when the next node does not advance in bit index. Then compare the stored key.
patricia_search(root, x):
node = root
prev = null
while prev == null or node.bit_index > prev.bit_index:
prev = node
if bit(x, node.bit_index) == 0:
node = node.left
else:
node = node.right
if node.key == x:
return true
return falseExample
Assume 4 bit keys:
| key | bits |
|---|---|
| 3 | 0011 |
| 5 | 0101 |
| 12 | 1100 |
Search for 5:
| step | node bit index | bit value | move |
|---|---|---|---|
| 1 | 1 | 1 | right |
| 2 | 2 | 0 | left |
| stop | - | - | compare stored key |
The final node contains key 5, so the search succeeds.
Correctness
Each node tests a bit position where stored keys differ. The traversal follows the same bit values as the target key, ensuring that only keys with matching prefixes remain possible.
The stopping condition detects when traversal cycles or stops progressing in bit index. At that point, the algorithm reaches a candidate node.
The final comparison verifies exact equality. If the stored key matches x, the key exists. Otherwise, no stored key has exactly the same bit pattern, so the key is absent.
Complexity
Let be the number of bits in the key.
| operation | time |
|---|---|
| search |
Since is fixed for machine integers, search runs in constant time relative to the number of stored keys.
Space complexity:
for iterative search.
When to Use
Patricia tries are useful when:
- keys are fixed length integers or bit strings
- memory efficiency matters
- prefix matching or longest prefix queries are required
- routing tables or networking applications are involved
Compared to full tries, Patricia tries reduce node count significantly by compressing paths.
Implementation
def bit(x, i):
return (x >> i) & 1
class PatriciaNode:
def __init__(self, key, bit_index):
self.key = key
self.bit_index = bit_index
self.left = self
self.right = self
def patricia_search(root, x):
node = root
prev = None
while prev is None or node.bit_index > prev.bit_index:
prev = node
if bit(x, node.bit_index) == 0:
node = node.left
else:
node = node.right
return node.key == xtype PatriciaNode struct {
Key uint64
BitIndex int
Left *PatriciaNode
Right *PatriciaNode
}
func bit(x uint64, i int) uint64 {
return (x >> i) & 1
}
func PatriciaSearch(root *PatriciaNode, x uint64) bool {
node := root
var prev *PatriciaNode
for prev == nil || node.BitIndex > prev.BitIndex {
prev = node
if bit(x, node.BitIndex) == 0 {
node = node.Left
} else {
node = node.Right
}
}
return node.Key == x
}