Incomputer science,binary search, also known ashalf-interval search,[1]logarithmic search,[2] orbinary chop,[3] is asearch algorithm that finds the position of a target value within asorted array.[4][5] Binary search compares the target value to the middle element of the array. If they are not equal, the half in which the target cannot lie is eliminated and the search continues on the remaining half, again taking the middle element to compare to the target value, and repeating this until the target value is found. If the search ends with the remaining half being empty, the target is not in the array.
Binary search runs inlogarithmic time in theworst case, making comparisons, where is the number of elements in the array.[a][6] Binary search is faster thanlinear search except for small arrays. However, the array must be sorted first to be able to apply binary search. There are specializeddata structures designed for fast searching, such ashash tables, that can be searched more efficiently than binary search. However, binary search can be used to solve a wider range of problems, such as finding the next-smallest or next-largest element in the array relative to the target even if it is absent from the array.
There are numerous variations of binary search. In particular,fractional cascading speeds up binary searches for the same value in multiple arrays. Fractional cascading efficiently solves a number of search problems incomputational geometry and in numerous other fields.Exponential search extends binary search to unbounded lists. Thebinary search tree andB-tree data structures are based on binary search.
Binary search works on sorted arrays. Binary search begins by comparing an element in the middle of the array with the target value. If the target value matches the element, its position in the array is returned. If the target value is less than the element, the search continues in the lower half of the array. If the target value is greater than the element, the search continues in the upper half of the array. By doing this, the algorithm eliminates the half in which the target value cannot lie in each iteration.[7]
Given an array of elements with values orrecordssorted such that, and target value, the followingsubroutine uses binary search to find the index of in.[7]
Set to and to.
If, the search terminates as unsuccessful.
Set (the position of the middle element) to plus thefloor of, which is the greatest integer less than or equal to.
If, set to and go to step 2.
If, set to and go to step 2.
Now, the search is done; return.
This iterative procedure keeps track of the search boundaries with the two variables and. The procedure may be expressed inpseudocode as follows, where the variable names and types remain the same as above,floor is thefloor function, andunsuccessful refers to a specific value that conveys the failure of the search.[7]
binary-search
function binary_search(A, n, T)is L := 0 R := n − 1while L ≤ Rdo m := L + floor((R - L) / 2)if A[m] < Tthen L := m + 1else if A[m] > Tthen R := m − 1else:return mreturn unsuccessful
Alternatively, the algorithm may take theceiling of. This may change the result if the target value appears more than once in the array.
In the above procedure, the algorithm checks whether the middle element () is equal to the target () in every iteration. Some implementations leave out this check during each iteration. The algorithm would perform this check only when one element is left (when). This results in a faster comparison loop, as one comparison is eliminated per iteration, while it requires only one more iteration on average.[8]
Set (the position of the middle element) to plus theceiling of, which is the least integer greater than or equal to.
If, set to.
Else,; set to.
Now, the search is done. If, return. Otherwise, the search terminates as unsuccessful.
Whereceil is the ceiling function, the pseudocode for this version is:
function binary_search_alternative(A, n, T)is L := 0 R := n − 1while L != Rdo m := L + ceil((R - L) / 2)if A[m] > Tthen R := m − 1else: L := mif A[L] = Tthenreturn Lreturn unsuccessful
The procedure may return any index whose element is equal to the target value, even if there are duplicate elements in the array. For example, if the array to be searched was and the target was, then it would be correct for the algorithm to either return the 4th (index 3) or 5th (index 4) element. The regular procedure would return the 4th element (index 3) in this case. It does not always return the first duplicate (consider which still returns the 4th element). However, it is sometimes necessary to find the leftmost element or the rightmost element for a target value that is duplicated in the array. In the above example, the 4th element is the leftmost element of the value 4, while the 5th element is the rightmost element of the value 4. The alternative procedure above will always return the index of the rightmost element if such an element exists.[9]
To find the leftmost element, the following procedure can be used:[10]
Set to and to.
While,
Set (the position of the middle element) to plus thefloor of, which is the greatest integer less than or equal to.
If, set to.
Else,; set to.
Return.
If and, then is the leftmost element that equals. Even if is not in the array, is therank of in the array, or the number of elements in the array that are less than.
Wherefloor is the floor function, the pseudocode for this version is:
function binary_search_leftmost(A, n, T): L := 0 R := nwhile L < R: m := L + floor((R - L) / 2)if A[m] < T: L := m + 1else: R := mreturn L
Binary search can be adapted to compute approximate matches. In the example above, the rank, predecessor, successor, and nearest neighbor are shown for the target value, which is not in the array.
The above procedure only performsexact matches, finding the position of a target value. However, it is trivial to extend binary search to perform approximate matches because binary search operates on sorted arrays. For example, binary search can be used to compute, for a given value, its rank (the number of smaller elements), predecessor (next-smallest element), successor (next-largest element), andnearest neighbor.Range queries seeking the number of elements between two values can be performed with two rank queries.[11]
Predecessor queries can be performed with rank queries. If the rank of the target value is, its predecessor is .[12]
For successor queries, theprocedure for finding the rightmost element can be used. If the result of running the procedure for the target value is, then the successor of the target value is .[12]
The nearest neighbor of the target value is either its predecessor or successor, whichever is closer.
Range queries are also straightforward.[12] Once the ranks of the two values are known, the number of elements greater than or equal to the first value and less than the second is the difference of the two ranks. This count can be adjusted up or down by one according to whether the endpoints of the range should be considered to be part of the range and whether the array contains entries matching those endpoints.[13]
Atree representing binary search. The array being searched here is, and the target value is.The worst case is reached when the search reaches the deepest level of the tree, while the best case is reached when the target value is the middle element.
In terms of the number of comparisons, the performance of binary search can be analyzed by viewing the run of the procedure on a binary tree. The root node of the tree is the middle element of the array. The middle element of the lower half is the left child node of the root, and the middle element of the upper half is the right child node of the root. The rest of the tree is built in a similar fashion. Starting from the root node, the left or right subtrees are traversed depending on whether the target value is less or more than the node under consideration.[6][14]
In the worst case, binary search makes iterations of the comparison loop, where the notation denotes thefloor function that yields the greatest integer less than or equal to the argument, and is thebinary logarithm. This is because the worst case is reached when the search reaches the deepest level of the tree, and there are always levels in the tree for any binary search.
The worst case may also be reached when the target element is not in the array. If is one less than a power of two, then this is always the case. Otherwise, the search may performiterations if the search reaches the deepest level of the tree. However, it may make iterations, which is one less than the worst case, if the search ends at the second-deepest level of the tree.[15]
On average, assuming that each element is equally likely to be searched, binary search makes iterations when the target element is in the array. This is approximately equal to iterations. When the target element is not in the array, binary search makes iterations on average, assuming that the range between and outside elements is equally likely to be searched.[14]
In the best case, where the target value is the middle element of the array, its position is returned after one iteration.[16]
In terms of iterations, no search algorithm that works only by comparing elements can exhibit better average and worst-case performance than binary search. The comparison tree representing binary search has the fewest levels possible as every level above the lowest level of the tree is filled completely.[b] Otherwise, the search algorithm can eliminate few elements in an iteration, increasing the number of iterations required in the average and worst case. This is the case for other search algorithms based on comparisons, as while they may work faster on some target values, the average performance overall elements is worse than binary search. By dividing the array in half, binary search ensures that the size of both subarrays are as similar as possible.[14]
Binary search requires three pointers to elements, which may be array indices or pointers to memory locations, regardless of the size of the array. Therefore, the space complexity of binary search is in theword RAMmodel of computation.
The average number of iterations performed by binary search depends on the probability of each element being searched. The average case is different for successful searches and unsuccessful searches. It will be assumed that each element is equally likely to be searched for successful searches. For unsuccessful searches, it will be assumed that theintervals between and outside elements are equally likely to be searched. The average case for successful searches is the number of iterations required to search every element exactly once, divided by, the number of elements. The average case for unsuccessful searches is the number of iterations required to search an element within every interval exactly once, divided by the intervals.[14]
In the binary tree representation, a successful search can be represented by a path from the root to the target node, called aninternal path. The length of a path is the number of edges (connections between nodes) that the path passes through. The number of iterations performed by a search, given that the corresponding path has lengthl, is counting the initial iteration. Theinternal path length is the sum of the lengths of all unique internal paths. Since there is only one path from the root to any single node, each internal path represents a search for a specific element. If there aren elements, which is a positive integer, and the internal path length is, then the average number of iterations for a successful search, with the one iteration added to count the initial iteration.[14]
Since binary search is the optimal algorithm for searching with comparisons, this problem is reduced to calculating the minimum internal path length of all binary trees withn nodes, which is equal to:[17]
For example, in a 7-element array, the root requires one iteration, the two elements below the root require two iterations, and the four elements below require three iterations. In this case, the internal path length is:[17]
The average number of iterations would be based on the equation for the average case. The sum for can be simplified to:[14]
Substituting the equation for into the equation for:[14]
For integern, this is equivalent to the equation for the average case on a successful search specified above.
Unsuccessful searches can be represented by augmenting the tree withexternal nodes, which forms anextended binary tree. If an internal node, or a node present in the tree, has fewer than two child nodes, then additional child nodes, called external nodes, are added so that each internal node has two children. By doing so, an unsuccessful search can be represented as a path to an external node, whose parent is the single element that remains during the last iteration. Anexternal path is a path from the root to an external node. Theexternal path length is the sum of the lengths of all unique external paths. If there are elements, which is a positive integer, and the external path length is, then the average number of iterations for an unsuccessful search, with the one iteration added to count the initial iteration. The external path length is divided by instead of because there are external paths, representing the intervals between and outside the elements of the array.[14]
This problem can similarly be reduced to determining the minimum external path length of all binary trees with nodes. For all binary trees, the external path length is equal to the internal path length plus.[17] Substituting the equation for:[14]
Substituting the equation for into the equation for, the average case for unsuccessful searches can be determined:[14]
Each iteration of the binary search procedure defined above makes one or two comparisons, checking if the middle element is equal to the target in each iteration. Assuming that each element is equally likely to be searched, each iteration makes 1.5 comparisons on average. A variation of the algorithm checks whether the middle element is equal to the target at the end of the search. On average, this eliminates half a comparison from each iteration. This slightly cuts the time taken per iteration on most computers. However, it guarantees that the search takes the maximum number of iterations, on average adding one iteration to the search. Because the comparison loop is performed only times in the worst case, the slight increase in efficiency per iteration does not compensate for the extra iteration for all but very large.[c][18][19]
In analyzing the performance of binary search, another consideration is the time required to compare two elements. For integers and strings, the time required increases linearly as the encoding length (usually the number ofbits) of the elements increase. For example, comparing a pair of 64-bit unsigned integers would require comparing up to double the bits as comparing a pair of 32-bit unsigned integers. The worst case is achieved when the integers are equal. This can be significant when the encoding lengths of the elements are large, such as with large integer types or long strings, which makes comparing elements expensive. Furthermore, comparingfloating-point values (the most common digital representation ofreal numbers) is often more expensive than comparing integers or short strings.
Fast floating point comparison is possible via comparing as an integer. However, this kind of comparison forms atotal order, which makesevery floating-point value compare differently from each other and the same as itself. This is different from the typical comparison where -0.0 should be the same as 0.0 and NaN should not compare the same as any other value including itself.[20][21]
According toSteel Bank Common Lisp contributor Paul Khuong, binary search leads to very fewbranch mispredictions despite its data-dependent nature. This is in part because most of it can be expressed asconditional moves instead of branches. The same applies to most logarithmic divide-and-conquer search algorithms.[22]
On most computer architectures, theprocessor has a hardwarecache separate fromRAM. Since they are located within the processor itself, caches are much faster to access but usually store much less data than RAM. Therefore, most processors store memory locations that have been accessed recently, along with memory locations close to it. For example, when an array element is accessed, the element itself may be stored along with the elements that are stored close to it in RAM, making it faster to sequentially access array elements that are close in index to each other (locality of reference). On a sorted array, binary search can jump to distant memory locations if the array is large, unlike algorithms (such aslinear search andlinear probing inhash tables) which access elements in sequence. This adds slightly to the running time of binary search for large arrays on most systems.[23]
Paul Khuong has noted that binary search on large (≥ 512 KiB) arrays of exactly a power-of-two size tends to cause an additional problem with how CPU caches are implemented. Specifically, thetranslation lookaside buffer (TLB) is often implemented as acontent-addressable memory (CAM), with the "key" usually being the lower bits of a requested address. When searching on an array of exactly a power-of-two size,memory address with the same lower bits tend to be accessed, causing collisions ("aliasing") with the "key" used to fetch the CAM. The typical TLB is 4-way associative, meaning it can handle at most four addresses hitting the same "key", after whichTLB thrashing happens. (Although the other levels of CPU caches also use a similar setup, they manage smaller areas with a higher way count, usually 8 or 16, so they are less affected.) This can be prevented by offsetting the split point of the binary search so it divides at31⁄64 instead of exactly the middle.[24]
Sorted arrays with binary search are a very inefficient solution when insertion and deletion operations are interleaved with retrieval, taking time for each such operation. In addition, sorted arrays can complicate memory use especially when elements are often inserted into the array.[25] There are other data structures that support much more efficient insertion and deletion. Binary search can be used to perform exact matching andset membership (determining whether a target value is in a collection of values). There are data structures that support faster exact matching and set membership. However, unlike many other searching schemes, binary search can be used for efficient approximate matching, usually performing such matches in time regardless of the type or structure of the values themselves.[26] In addition, there are some operations, like finding the smallest and largest element, that can be performed efficiently on a sorted array.[11]
Linear search is a simple search algorithm that checks every record until it finds the target value. Linear search can be done on alinked list, which allows for faster insertion and deletion than an array. Binary search is faster than linear search for sorted arrays except if the array is short, although the array needs to be sorted beforehand.[d][28] Allsorting algorithms based on comparing elements, such asquicksort andmerge sort, require at least comparisons in the worst case.[29] Unlike linear search, binary search can be used for efficient approximate matching. There are operations such as finding the smallest and largest element that can be done efficiently on a sorted array but not on an unsorted array.[30]
Binary search trees are searched using an algorithm similar to binary search.
Abinary search tree is abinary tree data structure that works based on the principle of binary search. The records of the tree are arranged in sorted order, and each record in the tree can be searched using an algorithm similar to binary search, taking on average logarithmic time. Insertion and deletion also require on average logarithmic time in binary search trees. This can be faster than the linear time insertion and deletion of sorted arrays, and binary trees retain the ability to perform all the operations possible on a sorted array, including range and approximate queries.[26][31]
However, binary search is usually more efficient for searching as binary search trees will most likely be imperfectly balanced, resulting in slightly worse performance than binary search. This even applies tobalanced binary search trees, binary search trees that balance their own nodes, because they rarely produce the tree with the fewest possible levels. Except for balanced binary search trees, the tree may be severely imbalanced with few internal nodes with two children, resulting in the average and worst-case search time approaching comparisons.[e] Binary search trees take more space than sorted arrays.[33]
Binary search trees lend themselves to fast searching in external memory stored in hard disks, as binary search trees can be efficiently structured in filesystems. TheB-tree generalizes this method of tree organization. B-trees are frequently used to organize long-term storage such asdatabases andfilesystems.[34][35]
For implementingassociative arrays,hash tables, a data structure that maps keys torecords using ahash function, are generally faster than binary search on a sorted array of records.[36] Most hash table implementations require onlyamortized constant time on average.[f][38] However, hashing is not useful for approximate matches, such as computing the next-smallest, next-largest, and nearest key, as the only information given on a failed search is that the target is not present in any record.[39] Binary search is ideal for such matches, performing them in logarithmic time. Binary search also supports approximate matches. Some operations, like finding the smallest and largest element, can be done efficiently on sorted arrays but not on hash tables.[26]
A related problem to search isset membership. Any algorithm that does lookup, like binary search, can also be used for set membership. There are other algorithms that are more specifically suited for set membership. Abit array is the simplest, useful when the range of keys is limited. It compactly stores a collection ofbits, with each bit representing a single key within the range of keys. Bit arrays are very fast, requiring only time.[40] The Judy1 type ofJudy array handles 64-bit keys efficiently.[41]
For approximate results,Bloom filters, another probabilistic data structure based on hashing, store aset of keys by encoding the keys using abit array and multiple hash functions. Bloom filters are much more space-efficient than bit arrays in most cases and not much slower: with hash functions, membership queries require only time. However, Bloom filters suffer fromfalse positives.[g][h][43]
There exist data structures that may improve on binary search in some cases for both searching and other operations available for sorted arrays. For example, searches, approximate matches, and the operations available to sorted arrays can be performed more efficiently than binary search on specialized data structures such asvan Emde Boas trees,fusion trees,tries, andbit arrays. These specialized data structures are usually only faster because they take advantage of the properties of keys with a certain attribute (usually keys that are small integers), and thus will be time or space consuming for keys that lack that attribute.[26] As long as the keys can be ordered, these operations can always be done at least efficiently on a sorted array regardless of the keys. Some structures, such as Judy arrays, use a combination of approaches to mitigate this while retaining efficiency and the ability to perform approximate matching.[41]
Uniform binary search stores the difference between the current and the two next possible middle elements instead of specific bounds.
Uniform binary search stores, instead of the lower and upper bounds, the difference in the index of the middle element from the current iteration to the next iteration. Alookup table containing the differences is computed beforehand. For example, if the array to be searched is[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], the middle element () would be6. In this case, the middle element of the left subarray ([1, 2, 3, 4, 5]) is3 and the middle element of the right subarray ([7, 8, 9, 10, 11]) is9. Uniform binary search would store the value of3 as both indices differ from6 by this same amount.[44] To reduce the search space, the algorithm either adds or subtracts this change from the index of the middle element. Uniform binary search may be faster on systems where it is inefficient to calculate the midpoint, such as ondecimal computers.[45]
Visualization ofexponential searching finding the upper bound for the subsequent binary search
Exponential search extends binary search to unbounded lists. It starts by finding the first element with an index that is both a power of two and greater than the target value. Afterwards, it sets that index as the upper bound, and switches to binary search. A search takes iterations before binary search is started and at most iterations of the binary search, where is the position of the target value. Exponential search works on bounded lists, but becomes an improvement over binary search only if the target value lies near the beginning of the array.[46]
Visualization ofinterpolation search using linear interpolation. In this case, no searching is needed because the estimate of the target's location within the array is correct. Other implementations may specify another function for estimating the target's location.
Instead of calculating the midpoint, interpolation search estimates the position of the target value, taking into account the lowest and highest elements in the array as well as length of the array. It works on the basis that the midpoint is not the best guess in many cases. For example, if the target value is close to the highest element in the array, it is likely to be located near the end of the array.[47]
A common interpolation function islinear interpolation. If is the array, are the lower and upper bounds respectively, and is the target, then the target is estimated to be about of the way between and. When linear interpolation is used, and the distribution of the array elements is uniform or near uniform, interpolation search makes comparisons.[47][48][49]
In practice, interpolation search is slower than binary search for small arrays, as interpolation search requires extra computation. Its time complexity grows more slowly than binary search, but this only compensates for the extra computation for large arrays.[47]
Infractional cascading, each array has pointers to every second element of another array, so only one binary search has to be performed to search all the arrays.
Fractional cascading is a technique that speeds up binary searches for the same element in multiple sorted arrays. Searching each array separately requires time, where is the number of arrays. Fractional cascading reduces this to by storing specific information in each array about each element and its position in the other arrays.[50][51]
Binary search has been generalized to work on certain types of graphs, where the target value is stored in a vertex instead of an array element. Binary search trees are one such generalization—when a vertex (node) in the tree is queried, the algorithm either learns that the vertex is the target, or otherwise which subtree the target would be located in. However, this can be further generalized as follows: given an undirected, positively weighted graph and a target vertex, the algorithm learns upon querying a vertex that it is equal to the target, or it is given an incident edge that is on the shortest path from the queried vertex to the target. The standard binary search algorithm is simply the case where the graph is a path. Similarly, binary search trees are the case where the edges to the left or right subtrees are given when the queried vertex is unequal to the target. For all undirected, positively weighted graphs, there is an algorithm that finds the target vertex in queries in the worst case.[52]
In noisy binary search, there is a certain probability that a comparison is incorrect.
Noisy binary search algorithms solve the case where the algorithm cannot reliably compare elements of the array. For each pair of elements, there is a certain probability that the algorithm makes the wrong comparison. Noisy binary search can find the correct position of the target with a given probability that controls the reliability of the yielded position. Every noisy binary search procedure must make at least comparisons on average, where is thebinary entropy function and is the probability that the procedure yields the wrong position.[53][54][55] The noisy binary search problem can be considered as a case of theRényi-Ulam game,[56] a variant ofTwenty Questions where the answers may be wrong.[57]
Classical computers are bounded to the worst case of exactly iterations when performing binary search.Quantum algorithms for binary search are still bounded to a proportion of queries (representing iterations of the classical procedure), but the constant factor is less than one, providing for a lower time complexity onquantum computers. Anyexact quantum binary search procedure—that is, a procedure that always yields the correct result—requires at least queries in the worst case, where is thenatural logarithm.[58] There is an exact quantum binary search procedure that runs in queries in the worst case.[59] In comparison,Grover's algorithm is the optimal quantum algorithm for searching an unordered list of elements, and it requires queries.[60]
The idea of sorting a list of items to allow for faster searching dates back to antiquity. The earliest known example was the Inakibit-Anu tablet from Babylon dating back toc. 200 BCE. The tablet contained about 500sexagesimal numbers and theirreciprocals sorted inlexicographical order, which made searching for a specific entry easier. In addition, several lists of names that were sorted by their first letter were discovered on theAegean Islands.Catholicon, a Latin dictionary finished in 1286 CE, was the first work to describe rules for sorting words into alphabetical order, as opposed to just the first few letters.[9]
WhenJon Bentley assigned binary search as a problem in a course for professional programmers, he found that ninety percent failed to provide a correct solution after several hours of working on it, mainly because the incorrect implementations failed to run or returned a wrong answer in rareedge cases.[66] A study published in 1988 shows that accurate code for it is only found in five out of twenty textbooks.[67] Furthermore, Bentley's own implementation of binary search, published in his 1986 bookProgramming Pearls, contained anoverflow error that remained undetected for over twenty years. TheJava programming language library implementation of binary search had the same overflow bug for more than nine years.[68]
In a practical implementation, the variables used to represent the indices will often be of fixed size (integers), and this can result in anarithmetic overflow for very large arrays. If the midpoint of the span is calculated as, then the value of may exceed the range of integers of the data type used to store the midpoint, even if and are within the range. If and are nonnegative, this can be avoided by calculating the midpoint as.[69]
An infinite loop may occur if the exit conditions for the loop are not defined correctly. Once exceeds, the search has failed and must convey the failure of the search. In addition, the loop must be exited when the target element is found, or in the case of an implementation where this check is moved to the end, checks for whether the search was successful or failed at the end must be in place. Bentley found that most of the programmers who incorrectly implemented binary search made an error in defining the exit conditions.[8][70]
C provides thefunctionbsearch() in itsstandard library, which is typically implemented via binary search, although the official standard does not require it so.[71]
C++'sstandard library provides the functionsbinary_search(),lower_bound(),upper_bound() andequal_range().[72] Using theC++20std::ranges library, it can be applied over arange asstd::ranges::binary_search().
D's standard library Phobos, instd.range module provides a typeSortedRange (returned bysort() andassumeSorted() functions) with methodscontains(),equaleRange(),lowerBound() andtrisect(), that use binary search techniques by default for ranges that offer random access.[73]
COBOL provides theSEARCH ALL verb for performing binary searches on COBOL ordered tables.[74]
Go'ssort standard library package contains the functionsSearch,SearchInts,SearchFloat64s, andSearchStrings, which implement general binary search, as well as specific implementations for searching slices of integers, floating-point numbers, and strings, respectively.[75]
Java offers a set ofoverloadedbinarySearch() static methods in the classesArrays andCollections in the standardjava.util package for performing binary searches on Java arrays and onLists, respectively.[76][77]
Microsoft's.NET Framework 2.0 offers staticgeneric versions of the binary search algorithm in its collection base classes. An example would beSystem.Array's methodBinarySearch<T>(T[] array, T value).[78]
^The isBig O notation, and is thelogarithm. In Big O notation, the base of the logarithm does not matter since every logarithm of a given base is a constant factor of another logarithm of another base. That is,, where is a constant.
^Any search algorithm based solely on comparisons can be represented using a binary comparison tree. Aninternal path is any path from the root to an existing node. Let be theinternal path length, the sum of the lengths of all internal paths. If each element is equally likely to be searched, the average case is or simply one plus the average of all the internal path lengths of the tree. This is because internal paths represent the elements that the search algorithm compares to the target. The lengths of these internal paths represent the number of iterationsafter the root node. Adding the average of these lengths to the one iteration at the root yields the average case. Therefore, to minimize the average number of comparisons, the internal path length must be minimized. It turns out that the tree for binary search minimizes the internal path length.Knuth 1998 proved that theexternal path length (the path length over all nodes where both children are present for each already-existing node) is minimized when the external nodes (the nodes with no children) lie within two consecutive levels of the tree. This also applies to internal paths as internal path length is linearly related to external path length. For any tree of nodes,. When each subtree has a similar number of nodes, or equivalently the array is divided into halves in each iteration, the external nodes as well as their interior parent nodes lie within two levels. It follows that binary search minimizes the number of average comparisons as its comparison tree has the lowest possible internal path length.[14]
^Knuth 1998 showed on hisMIX computer model, which Knuth designed as a representation of an ordinary computer, that the average running time of this variation for a successful search is units of time compared to units for regular binary search. The time complexity for this variation grows slightly more slowly, but at the cost of higher initial complexity.[18]
^Knuth 1998 performed a formal time performance analysis of both of these search algorithms. On Knuth'sMIX computer, which Knuth designed as a representation of an ordinary computer, binary search takes on average units of time for a successful search, while linear search with a sentinel node at the end of the list takes units. Linear search has lower initial complexity because it requires minimal computation, but it quickly outgrows binary search in complexity. On the MIX computer, binary search only outperforms linear search with a sentinel if.[14][27]
^Inserting the values in sorted order or in an alternating lowest-highest key pattern will result in a binary search tree that maximizes the average and worst-case search time.[32]
^It is possible to search some hash table implementations in guaranteed constant time.[37]
^This is because simply setting all of the bits which the hash functions point to for a specific key can affect queries for other keys which have a common hash location for one or more of the functions.[42]
^There exist improvements of the Bloom filter which improve on its complexity or support deletion; for example, the cuckoo filter exploitscuckoo hashing to gain these advantages.[42]
^That is, arrays of length 1, 3, 7, 15, 31 ...[62]
^abFan, Bin; Andersen, Dave G.; Kaminsky, Michael; Mitzenmacher, Michael D. (2014).Cuckoo filter: practically better than Bloom. Proceedings of the 10th ACM International on Conference on Emerging Networking Experiments and Technologies. pp. 75–88.doi:10.1145/2674005.2674994.
^Rényi, Alfréd (1961). "On a problem in information theory".Magyar Tudományos Akadémia Matematikai Kutató Intézetének Közleményei (in Hungarian).6:505–516.MR0143666.