Search starting from a known nearby position, achieving time proportional to distance rather than full size.
Finger search exploits locality. Instead of searching from the root or beginning, it starts from a known position called a finger and moves toward the target. The cost depends on the distance between the finger and the target, not the total size of the structure.
This method appears in ordered data structures such as balanced trees, skip lists, and sorted arrays with auxiliary links.
Problem
Given an ordered sequence or structure and a finger position , find an index such that
Assume is close to .
Idea
Let be the distance between the finger and the target. Finger search aims to run in
instead of .
The algorithm navigates locally from the finger, often moving up the structure to find a suitable ancestor, then descending toward the target.
Algorithm (BST Variant)
In a balanced binary search tree, maintain parent pointers.
finger_search(node f, x):
u = f
while u != null:
if u.key == x:
return u
if x < u.key:
if u.left != null:
u = u.left
else:
u = u.parent
else:
if u.right != null:
u = u.right
else:
u = u.parent
return nullIn practice, the algorithm first climbs up until it finds a subtree that could contain , then performs a standard search downward.
Example
Consider a sorted array:
Finger at index (value ), target .
Distance:
Search proceeds locally:
| step | index | value | action |
|---|---|---|---|
| 1 | 3 | 12 | move right |
| 2 | 4 | 16 | move right |
| 3 | 5 | 20 | found |
The cost depends on , not .
Correctness
Because the structure is ordered, local comparisons preserve correctness. Moving upward ensures that no possible subtree containing is skipped. The descent phase mirrors standard search, restricted to a smaller region.
Complexity
| structure | time |
|---|---|
| balanced BST | |
| skip list | |
| array with links |
Space:
When to Use
Finger search is effective when:
- successive queries are close in value
- data access exhibits locality
- the structure supports navigation from arbitrary nodes
It is common in editors, sequence data structures, and streaming order statistics.
Implementation (Array, simple form)
def finger_search_array(a, f, x):
n = len(a)
i = f
if a[i] == x:
return i
if a[i] < x:
i += 1
while i < n and a[i] <= x:
if a[i] == x:
return i
i += 1
else:
i -= 1
while i >= 0 and a[i] >= x:
if a[i] == x:
return i
i -= 1
return -1func FingerSearchArray(a []int, f int, x int) int {
n := len(a)
i := f
if a[i] == x {
return i
}
if a[i] < x {
for i = i + 1; i < n && a[i] <= x; i++ {
if a[i] == x {
return i
}
}
} else {
for i = i - 1; i >= 0 && a[i] >= x; i-- {
if a[i] == x {
return i
}
}
}
return -1
}