Interpolation Search — 40x Slowdown on Skewed Data
Interpolation search latency spiked from <5ms to >200ms on real stock data due to skewed distribution — O(n) behavior.
20+ years shipping performance-critical code where algorithms decide the bill. Written from production experience, not tutorials.
- ✓Solid grasp of fundamentals
- ✓Comfortable reading code examples
- ✓Basic production concepts
- Interpolation search estimates probe position using value distribution, not midpoint.
- Formula: pos = lo + ((target - arr[lo]) × (hi - lo)) / (arr[hi] - arr[lo])
- Average complexity O(log log n) — dramatically faster than binary search's O(log n) on uniform data.
- Worst case O(n) — happens when data is not uniformly distributed (e.g., exponential or clustered).
- Real-world use: database query planners use similar interpolation logic via histogram statistics.
- Performance trade-off: requires sorted array and meaningful distance metric between values.
Interpolation search is a search algorithm for sorted arrays that, unlike binary search which always checks the middle element, probes the position based on the value being searched. It uses a linear interpolation formula — pos = low + ((key - arr[low]) * (high - low)) / (arr[high] - arr[low]) — to estimate where the target might be, similar to how you'd look up a name in a phone book by flipping to the approximate page rather than splitting the book in half every time.
This makes it dramatically faster than binary search on uniformly distributed data, achieving O(log log n) average time complexity compared to binary search's O(log n).
In practice, interpolation search shines when you have large, sorted datasets with roughly uniform key distributions — think database index lookups on auto-increment IDs, timestamped log files, or evenly distributed numeric keys. However, it falls apart catastrophically on skewed or non-uniform data.
The classic pathological case is searching for a value in an exponentially growing sequence like [1, 2, 4, 8, 16, ...] — here, interpolation search degrades to O(n) because each probe lands near the same endpoint, while binary search maintains O(log n). Real-world measurements show this can cause a 40x slowdown compared to binary search on such skewed distributions.
The algorithm is a niche tool, not a general replacement for binary search. You should reach for it only when you know your data is uniformly distributed and the array is large enough that the O(log log n) vs O(log n) difference matters. For most production code, especially in systems where data distribution isn't guaranteed, binary search remains the safer default.
Libraries like C++'s std::lower_bound and Python's bisect module don't implement interpolation search for this reason — the worst-case risk outweighs the average-case gain in general-purpose contexts.
Binary search always checks the middle element. But if you're looking for 'Z' in a phone book, you don't open to the middle — you go near the end. Interpolation search does exactly this: estimate where the target is based on its value relative to the range, like proportional placement on a ruler. For uniformly distributed data, this gives O(log log n) — dramatically faster than binary search's O(log n).
Interpolation search achieves O(log log n) on uniformly distributed data — compared to binary search's O(log n). For n=10^9 uniformly distributed integers, that is ~5 probes versus ~30 probes. For the right data, that is a 6x speedup in comparison count.
The catch: 'uniformly distributed' is rarely guaranteed in real data. Database query optimisers use similar interpolation logic — estimating where a value falls in a range based on column statistics and histograms. That is interpolation search applied to index structures. Understanding interpolation search means understanding how query planners estimate probe costs.
Interpolation Search: When Binary Search Fails on Real-World Data
Interpolation search is a search algorithm for sorted arrays that estimates the position of a target value using a linear interpolation formula, rather than always splitting the array in half. Given a sorted array arr and a target x, it computes the probe position as: low + ((x - arr[low]) * (high - low)) / (arr[high] - arr[low]). This is the same calculation you'd use to find a point on a line between two known points — it assumes the data is roughly uniformly distributed.
In practice, interpolation search achieves O(log log n) average-case time on uniformly distributed data, which is significantly faster than binary search's O(log n). However, its worst-case performance is O(n) — for example, when data is exponentially or quadratically skewed. Each probe can land far from the target, degrading to linear scans. The algorithm relies on the assumption that the key distribution is close to uniform; when that assumption breaks, performance collapses.
Use interpolation search only when you have a sorted array with a known uniform or near-uniform distribution — such as evenly spaced timestamps, sequential IDs, or sensor readings. It's not a drop-in replacement for binary search. In production systems, the risk of O(n) behavior on skewed data (e.g., log-normal latencies, Pareto-distributed request sizes) makes it a niche tool, not a general-purpose search. Most standard library implementations (Java's Arrays.binarySearch, C++'s std::lower_bound) stick with binary search for this reason.
The Interpolation Formula
Instead of mid = (lo + hi) // 2, interpolation search estimates: pos = lo + ((target - arr[lo]) × (hi - lo)) / (arr[hi] - arr[lo])
This is linear interpolation — projecting where the target would fall if values were uniformly distributed between arr[lo] and arr[hi].
def interpolation_search(arr: list, target) -> int: lo, hi = 0, len(arr) - 1 while lo <= hi and arr[lo] <= target <= arr[hi]: if lo == hi: return lo if arr[lo] == target else -1 # Interpolation probe pos = lo + int((target - arr[lo]) * (hi - lo) / (arr[hi] - arr[lo])) if arr[pos] == target: return pos elif arr[pos] < target: lo = pos + 1 else: hi = pos - 1 return -1 # Uniformly distributed data — very fast arr = list(range(0, 1000, 10)) # [0, 10, 20, ..., 990] print(interpolation_search(arr, 680)) # 68 print(interpolation_search(arr, 777)) # -1 (not a multiple of 10)
C++ and Python Implementations
The previous section showed the Python implementation. Here is the equivalent C++ version for those working in systems-level contexts like trading engines or game servers. C++ requires careful handling of integer types to avoid overflow. The logic mirrors the Python version exactly.
#include <iostream> #include <vector> #include <cstdint> int interpolation_search(const std::vector<int>& arr, int target) { int lo = 0, hi = arr.size() - 1; while (lo <= hi && arr[lo] <= target && target <= arr[hi]) { if (lo == hi) { return (arr[lo] == target) ? lo : -1; } // Use 64-bit arithmetic to avoid overflow int64_t numerator = static_cast<int64_t>(target - arr[lo]) * (hi - lo); int64_t denominator = arr[hi] - arr[lo]; int pos = lo + static_cast<int>(numerator / denominator); if (arr[pos] == target) return pos; else if (arr[pos] < target) lo = pos + 1; else hi = pos - 1; } return -1; } int main() { std::vector<int> arr = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}; std::cout << interpolation_search(arr, 60) << std::endl; // 6 std::cout << interpolation_search(arr, 55) << std::endl; // -1 return 0; }
When It Excels vs When It Fails
Excels: Uniformly distributed sorted arrays — phone books, sorted numeric IDs, timestamps at regular intervals. O(log log n) expected.
Fails badly: Non-uniform distributions — geometric sequences, or data clustered at one end. Worst case O(n). Example: arr = [1, 2, 4, 8, 16, ..., 2^n] — interpolation probes near the start every time for large targets.
Rule of thumb: Use interpolation when you know the data is roughly uniform. Use binary search otherwise.
Advantages and Disadvantages
The table below contrasts interpolation search's behaviour on uniform versus non‑uniform distributions:
Complexity Analysis
Average (uniform data): O(log log n) — the probe reduces search space multiplicatively Worst case: O(n) — non-uniform distribution can make it probe one element at a time Space: O(1)
For n=10^9 uniform elements: log log n ≈ 5 probes vs binary search's log n ≈ 30 probes.
O(log log n) vs O(n) Boundary Cases
The following table lists explicit boundary conditions that determine whether interpolation search performs in O(log log n) or degrades to O(n). Understanding these helps you write guards in production.
Real-World Application: Database Query Planning
Database systems like PostgreSQL and MySQL use histogram statistics to estimate where a value falls within an index range. For example, a B-tree range scan estimates the number of pages to traverse based on column value distribution — that's interpolation search on index pages.
Query planners maintain histogram buckets (e.g., 100 equal-height buckets). For a WHERE clause like age = 35, the planner does: estimate position = bucket_start + ((35 - bucket_min) * bucket_width / (bucket_max - bucket_min)). Sound familiar? It's exactly the interpolation formula.
If the histogram shows uniform distribution, the planner assumes few pages to scan. If skewed, it may choose a full index scan instead.
pg_stats histogram bounds vs actual data distribution; set auto-analyze thresholds aggressively for volatile tables.Comparison with Binary Search: When to Choose Which
| Aspect | Interpolation Search | Binary Search |
|---|---|---|
| Average complexity | O(log log n) | O(log n) |
| Worst-case complexity | O(n) | O(log n) |
| Data requirement | Uniform distribution | Any sorted data |
| Extra operations | Multiplication/division per probe | Bit shift/addition |
| Cache friendliness | Worse (random-like probe positions) | Better (midpoint often in same cache line) |
| Integer overflow risk | Yes | No |
For most production systems, binary search is the safer default. Use interpolation search only when: - Data is proven to be near-uniform (e.g., auto-increment IDs with no gaps) - The search array is in DRAM (not disk) — random probe positions kill HDD/SSD seek costs - Worst-case O(n) is acceptable or mitigated by fallback
Recursive Implementation in Java
For completeness, here is a recursive variant of interpolation search in Java. Recursion avoids the explicit while loop but adds stack overhead. In practice, the iterative approach is preferred for performance and to avoid stack overflow on large inputs.
public class InterpolationSearchRecursive { public static int search(int[] arr, int target, int lo, int hi) { if (lo > hi || arr[lo] > target || arr[hi] < target) { return -1; } if (lo == hi) { return (arr[lo] == target) ? lo : -1; } // Avoid division by zero if (arr[hi] == arr[lo]) { return (arr[lo] == target) ? lo : -1; } int pos = lo + (int)(((long)(target - arr[lo]) * (hi - lo)) / (arr[hi] - arr[lo])); if (arr[pos] == target) { return pos; } else if (arr[pos] < target) { return search(arr, target, pos + 1, hi); } else { return search(arr, target, lo, pos - 1); } } public static void main(String[] args) { int[] arr = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}; System.out.println(search(arr, 60, 0, arr.length - 1)); // 6 System.out.println(search(arr, 55, 0, arr.length - 1)); // -1 } }
Why Probe Position Matters (And When It Lies to You)
Binary search always guesses the midpoint. Interpolation search uses a weighted guess based on the actual values. That's the entire point — and the entire risk.
The formula low + ((high - low) / (arr[high] - arr[low])) * (target - arr[low]) estimates where the target should be if the data were uniformly distributed. In practice, uniform distribution is rare. When it holds, you get O(log log n) time. When it doesn't, the probe position becomes a lie — sending you to the wrong half, sometimes repeatedly.
Here's the mental model: think of it like estimating a book's page number by its weight. If every page is the same thickness, you'll be close. If some chapters are on tissue paper and others on cardboard, you're guessing blind.
The real skill is knowing when the assumption holds. Log data, timestamps from evenly sampled sensors, sequential IDs — those are safe. Zipfian distributions, clustered values, or skewed ranges? Don't trust the probe. Fall back to binary search or pre-check the distribution.
Bottom line: the probe formula is a heuristic, not a law. Treat it like one.
// io.thecodeforge — dsa tutorial public class ProbeAccuracyCheck { // Simulates how often the probe lands near the target // for different data distributions public static double probeAccuracy(int[] arr, int target) { int low = 0, high = arr.length - 1; int correctGuesses = 0; int attempts = 10000; for (int i = 0; i < attempts; i++) { int probe = low + (int)((double)(high - low) / (arr[high] - arr[low]) * (target - arr[low])); if (probe >= low && probe <= high && arr[probe] == target) { correctGuesses++; } // Shift target slightly to simulate noise target += (Math.random() > 0.5) ? 1 : -1; } return (double) correctGuesses / attempts * 100; } public static void main(String[] args) { int[] uniform = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100}; int[] skewed = {1, 2, 3, 4, 5, 6, 7, 8, 9, 1000}; System.out.println("Uniform accuracy: " + probeAccuracy(uniform, 50) + "%"); System.out.println("Skewed accuracy: " + probeAccuracy(skewed, 5) + "%"); } }
Real Implementation Gotchas (That Tutorials Never Show You)
Every tutorial shows the clean formula. None mention the integer overflow landmine. When high and low are large (say, arrays with millions of elements), (high - low) can overflow a signed 32-bit integer. Java wraps it, Python doesn't care, C++ silently corrupts memory.
Fix: use low + ((high - low) / 2) for binary search, but for interpolation the formula expands. In production, cast to long before multiplication or use Math.subtractExact(). The snippet below shows the safe version.
Second gotcha: division by zero. When arr[high] == arr[low], the formula divides by zero. This happens with duplicate values or when the search range collapses to identical elements. Always guard with if (arr[low] == arr[high]) — fall back to linear check or binary search. The "algorithm" steps from competitors ignore this entirely; it'll crash in production on the first duplicate-laden dataset.
Third: probe position can go out of bounds. The formula assumes the target is between low and high. If not, you get negative indices or index past the array. Guard with bounds check after every probe calculation.
These aren't edge cases. They're the norm with real-world data: duplicates, near-duplicates, and large arrays.
// io.thecodeforge — dsa tutorial public class SafeInterpolationSearch { public static int search(int[] arr, int target) { int low = 0; int high = arr.length - 1; while (low <= high && target >= arr[low] && target <= arr[high]) { // Guard: division by zero on duplicates if (arr[low] == arr[high]) { // Fallback: linear scan in this range for (int i = low; i <= high; i++) { if (arr[i] == target) return i; } return -1; } // Safe probe: cast to long to avoid overflow long probe = low + ((long)(high - low) * (target - arr[low]) / (arr[high] - arr[low])); // Bounds check (theoretical, but paranoia pays) if (probe < low || probe > high) break; int idx = (int) probe; if (arr[idx] == target) return idx; if (arr[idx] < target) low = idx + 1; else high = idx - 1; } return -1; } public static void main(String[] args) { int[] data = {1, 3, 5, 7, 9, 9, 9, 11, 13, 15}; System.out.println("Search 9: " + search(data, 9)); System.out.println("Search 10: " + search(data, 10)); } }
Probabilistic Performance: Why Worst-Case Data Will Bite You
The O(log log n) average-case complexity only holds under one assumption: uniform distribution of data. The moment your data is clustered, skewed, or exhibits any pattern other than uniform, interpolation search degrades faster than a rusty nail. In the worst case — think exponential gaps or adversarial key placement — each probe can land on the same element, collapsing performance to O(n).
Real production systems don't get perfect input. They get user-generated timestamps, sensor readings with noise, and database indices with missing values. If you're considering interpolation search for anything other than a controlled environment, benchmark against your actual distribution first. Run a histogram on your keys. If the CDF isn't close to linear, you're gambling, not engineering.
The rule: Do not trust the asymptotics. Test against your real data. Interpolation search is a precision tool, not a drop-in binary search replacement.
// io.thecodeforge — dsa tutorial import java.util.*; public class DistributionTest { // Simulates worst-case linear probes on skewed data static int interpolationSearch(int[] arr, int target) { int lo = 0, hi = arr.length - 1, probes = 0; while (lo <= hi && target >= arr[lo] && target <= arr[hi]) { probes++; if (lo == hi) break; int pos = lo + ((target - arr[lo]) * (hi - lo)) / (arr[hi] - arr[lo]); if (arr[pos] == target) return probes; if (arr[pos] < target) lo = pos + 1; else hi = pos - 1; } return -probes; // negative count to show probes even on failure } public static void main(String[] args) { int[] exponentialGap = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512}; int result = interpolationSearch(exponentialGap, 32); System.out.println("Probes on exponential data: " + Math.abs(result)); } }
Demo Program: Watch Interpolation Lie to You
The best way to kill a library is to blast it through a demo that tests its boundaries. This Java program does exactly that: it compares interpolation search against binary search on three datasets — uniform, skewed, and adversarial. You'll see the probe count explode on the adversarial case.
Why does this matter? Because tutorials show clean runs. Production shows dirty data. When the probe formula guesses wrong repeatedly, you're burning cache lines and wall clock. The demo prints probe counts per search so you can measure the lie yourself. Notice how on the skewed list, interpolation uses more probes than binary search's ceiling of log2(n).
Builders know their tools. Run this demo with your own data. If you see probe counts spike, kill the interpolation search and fall back to binary. Your latency SLA will thank you.
// io.thecodeforge — dsa tutorial import java.util.*; public class ProbeComparisonDemo { static int binSearch(int[] a, int t) { int l=0, r=a.length-1, p=0; while(l<=r){ p++; int m=l+(r-l)/2; if(a[m]==t) return p; if(a[m]<t) l=m+1; else r=m-1; } return -p; } static int interpSearch(int[] a, int t) { int l=0, r=a.length-1, p=0; while(l<=r && t>=a[l] && t<=a[r]){ p++; if(l==r) break; int m=l+((t-a[l])*(r-l))/(a[r]-a[l]); if(a[m]==t) return p; if(a[m]<t) l=m+1; else r=m-1; } return -p; } public static void main(String[] args) { Random r = new Random(); int[] uniform = r.ints(100, 0, 1000).sorted().toArray(); int[] skewed = new int[100]; for(int i=0;i<100;i++) skewed[i]=(int)Math.pow(i,2); int target = uniform[42]; System.out.println("Binary probes (uniform): "+Math.abs(binSearch(uniform, target))); System.out.println("Interp probes (uniform): "+Math.abs(interpSearch(uniform, target))); target = skewed[42]; System.out.println("Binary probes (skewed): "+Math.abs(binSearch(skewed, target))); System.out.println("Interp probes (skewed): "+Math.abs(interpSearch(skewed, target))); } }
Pseudocode: The Abstract Engine That Drives Interpolation Search
Before diving into implementation, you need the pseudocode — it strips away language syntax to expose the search logic. The core loop: while the target lies within the current search bounds (low to high), compute a probe position using interpolation. Unlike binary search’s midpoint, this probe is weighted by the value difference: probe = low + ((high - low) * (target - arr[low]) / (arr[high] - arr[low])). If the probe’s value equals the target, return index. If it’s too high, shrink the high bound; if too low, raise the low bound. The loop exits when the target falls outside the range or the probe index becomes invalid. Critical nuance: if arr[high] equals arr[low], the division fails — handle that degenerate uniform data case by falling back to linear search. This pseudocode forces you to see why uniform distributions work: the probe lands near the target. Non-uniform distributions break that assumption, making probes unreliable.
// io.thecodeforge — dsa tutorial public class InterpolationSearchLogic { static int search(int[] sortedArr, int target) { int low = 0, high = sortedArr.length - 1; while (low <= high && target >= sortedArr[low] && target <= sortedArr[high]) { if (sortedArr[high] == sortedArr[low]) { // Uniform values: fallback to linear scan for (int i = low; i <= high; i++) if (sortedArr[i] == target) return i; return -1; } int probe = low + ((high - low) * (target - sortedArr[low])) / (sortedArr[high] - sortedArr[low]); if (sortedArr[probe] == target) return probe; if (sortedArr[probe] < target) low = probe + 1; else high = probe - 1; } return -1; } }
Solution: Why Binary Search Still Dominates Most Production Data
You don’t pick interpolation search because it’s clever. You pick it because your data passes two tests: sorted and uniformly distributed (like primary key IDs in a dense integer sequence). The solution for when to use it: first, sample 100 random elements from your array. If the gaps between consecutive sorted values have low variance (e.g., standard deviation < 20% of mean gap), interpolation will outperform binary search by 30-50%. If variance is high — typical in real-world strings, sparse IDs, or timestamps with bursts — binary search wins with its guaranteed O(log n) worst case. The production solution: write a hybrid that starts with interpolation but counts probes. If after 5 probes the array bounds haven’t halved, switch to binary search. This gives you the best of both: O(log log n) on uniform data, O(log n) guaranteed otherwise. Never use interpolation on strings, floating-point data with NaN/infinity, or on arrays smaller than 1000 elements — the overhead of the probe calculation negates any benefit.
// io.thecodeforge — dsa tutorial public class HybridSearch { static int search(int[] a, int t) { int l = 0, r = a.length - 1, probes = 0; while (l <= r && t >= a[l] && t <= a[r]) { if (++probes > 5) // fallback to binary return binaryFallback(a, t, l, r); if (a[r] == a[l]) { for (int i = l; i <= r; i++) if (a[i] == t) return i; return -1; } int p = l + ((r - l) * (t - a[l])) / (a[r] - a[l]); if (a[p] == t) return p; if (a[p] < t) l = p + 1; else r = p - 1; } return -1; } static int binaryFallback(int[] a, int t, int l, int r) { while (l <= r) { int m = l + (r - l) / 2; if (a[m] == t) return m; if (a[m] < t) l = m + 1; else r = m - 1; } return -1; } }
Interpolation Search on Stock Price Data: A 10x Slowdown
- Never assume data distribution is uniform without runtime validation — real-world data is often skewed.
- Interpolation search should degrade gracefully: fall back to binary search if the probe position is too close to previous bounds.
- Monitor search latency per query pattern; a sudden spike often indicates distribution change.
python3 -c "import sys; arr=list(map(int,sys.stdin)); n=len(arr); bins=[0]*10; step=(arr[-1]+1-arr[0])//10; [bins[int((v-arr[0])/step)] for v in arr]; print(bins)"Check if any bin has >2x the average (n/10). If yes, distribution is non-uniform.Add logging: print(f"lo={lo}, hi={hi}, pos={pos}, arr[pos]={arr[pos]}") inside loop.Verify integer overflow: pos = lo + (int)((long)(target - arr[lo]) * (hi - lo) / (arr[hi] - arr[lo]))| Aspect | Interpolation Search | Binary Search |
|---|---|---|
| Average complexity | O(log log n) | O(log n) |
| Worst-case complexity | O(n) | O(log n) |
| Data requirement | Uniform distribution | Any sorted data |
| Extra operations per probe | Multiplication/division | Bit shift or addition |
| Cache friendliness | Poor — random probe positions | Good — often same cache line |
| Integer overflow risk | Yes (without 64-bit guard) | No |
| Real-world usage | Database query planning | Everywhere (stdlib sort/search) |
| File | Command / Code | Purpose |
|---|---|---|
| interpolation_search.py | def interpolation_search(arr: list, target) -> int: | The Interpolation Formula |
| interpolation_search.cpp | int interpolation_search(const std::vector | C++ and Python Implementations |
| io | public class InterpolationSearchRecursive { | Recursive Implementation in Java |
| ProbeAccuracyCheck.java | public class ProbeAccuracyCheck { | Why Probe Position Matters (And When It Lies to You) |
| SafeInterpolationSearch.java | public class SafeInterpolationSearch { | Real Implementation Gotchas (That Tutorials Never Show You) |
| DistributionTest.java | public class DistributionTest { | Probabilistic Performance |
| ProbeComparisonDemo.java | public class ProbeComparisonDemo { | Demo Program |
| InterpolationSearchLogic.java | public class InterpolationSearchLogic { | Pseudocode |
| HybridSearch.java | public class HybridSearch { | Solution |
Key takeaways
Common mistakes to avoid
3 patternsUsing interpolation search on non-integer data types
Not guarding against division by zero when arr[hi] == arr[lo]
Assuming uniform distribution without validation
Practice These on LeetCode
Interview Questions on This Topic
Derive the interpolation formula and explain what it assumes about the data.
When does interpolation search degrade to O(n)?
Compare interpolation search with binary search — when would you choose each?
What is the expected number of probes for interpolation search on uniform data?
How do database query planners use interpolation search?
age BETWEEN 30 AND 40, the planner uses interpolation: given the bucket's min and max values and the target values, it estimates the fraction of rows that fall in that range. This is exactly the interpolation search formula applied to cumulative frequencies. The accuracy depends on fresh histograms; stale statistics cause wrong estimates and bad query plans.Frequently Asked Questions
No — it requires a meaningful distance metric between values to compute the interpolation. It works for integers, floats, and dates (after conversion to timestamps), but not arbitrary comparable types like strings (lexicographic comparison doesn't give arithmetic difference).
No — the algorithm relies on the array being sorted. The bounds check arr[lo] <= target <= arr[hi] and the probe formula assume ascending order. Use unsorted search methods like linear search or hash tables instead.
Interpolation search works correctly with duplicates — it will find one occurrence (likely the first encountered by the probe). The algorithm doesn't guarantee which duplicate is returned unless you perform linear scan around the match. For finding all occurrences, binary search with lower/upper bound is better.
Not as a general-purpose search — most languages' standard library sort/search (Java's Arrays.binarySearch, Python's bisect) use binary search. However, database internal statistics (PostgreSQL's pg_stats, MySQL's index dives) use interpolation-like logic for cardinality estimation. Also, some specialized hash table implementations (e.g., Facebook's Folly F14) use interpolation in probe sequences.
21 interactive demos — binary search, BST, AVL trees, LCA, segment trees, tries, Morris traversal, Fenwick trees, and 4 advanced search algorithms. The definitive reference with 12 interview Q&As.
20+ years shipping performance-critical code where algorithms decide the bill. Written from production experience, not tutorials.
That's Searching. Mark it forged?
7 min read · try the examples if you haven't