function jumpSearch(array: number[], target: number) {const block = Math.floor(Math.sqrt(array.length));
let previous = 0, next = block;
while (array[Math.min(next, array.length) - 1] < target) {previous = next;
next += block;
if (previous >= array.length) return -1;
}
for (let index = previous; index < Math.min(next, array.length); index++) {if (array[index] === target) return index;
}
return -1;
}
Look for 33. Block size is ⌊√32⌋ = 5: jump that far, check the last element of the block.
Understanding Jump search
The idea
Jump search reads only the last element of each block of √n elements. While that element is smaller than the target the whole block can be skipped; the first block whose last element is not smaller must contain the target, if it is anywhere, and a linear scan of that block finds it.
Both phases cost at most √n comparisons, so the total is about 2√n. That is far worse than binary search's log n, but every comparison after a jump moves forward through memory, which matters on tape, on linked storage or when jumping back is expensive.
The four stages
Complexity
Versus its siblings
Pseudocode
JUMPSEARCH(array, target)
block ← ⌊√n⌋; previous ← 0; next ← block
while array[min(next, n) − 1] < target: previous ← next; next ← next + block
for index ← previous to min(next, n) − 1: if array[index] = target: return index
return −1
When to use
Pitfalls
History
Jump search is folklore from the era of sequential storage; Ben Shneiderman analysed it in 1978 in a paper on searching sorted sequential files, where he showed the √n block is optimal for one level of jumping and √n^(2/3)-style blocks for two.