Although linear search is far inferior to binary search in terms of efficiency, there are times when only linear search is applicable.
Searching in a linked list can only be done using linear search. Searching in an unsorted array can only be done using linear search.
The algorithm of linear search is in listing 1.
Just a little bit of explanation for this pseudocode.
Let us perform the worst case analysis. In the worst case, the value v does not match any item in the sequence. Line 6 and lines 10 to 14 execute only once, and none of these lines involve repetitive actions. We’ll lump the execution time of all these lines as .
How many times do we execute line 7? Assuming that is not found in the sequence, it means the right condition of the conjunction is always true. This means that we can only count on the left condition to become false to exit the loop.
The iterator i begins at the beginning of the sequence. We only increments once in the loop. It will require increments to reach the end of the sequence ( means the number of values in the sequence). Consequently, line 7 executes times, while line 8 executes times. Let us assume line 7 requires for each execution, and line 8 requires for each execution, the total amount of time required is . Let us call „ , and , then .
The upper bound of can be many functions, such as . However, the tight bound of can only be . Let us revisit the definitions of asymptotic limits in the context of .
Here, we can use the usual limit in place of limit inferior because the sequence is monotonic. The interpretation is that .
Next, applying the same techniques, we can show that . This means that .
Since and , .
Binary search is useful only when values are stored in a randomly accessible way, and they are sorted. This limits the use of binary search to arrays in memory, or randomly accessiable files of equal size records (or one with an index).
Listing 2 is the pseudocode of binary search as a recursive algorithm.
Let us now analyze the complexity of binary search. Again, we are only interested in the worst case complexity, which means the value v cannot be found in the random access ADT a.
Looking through the recursive algorithm, only a few lines do not take constant time to execute. Line 13 and line 15 invokes the subroutine again. This means that the execution time of an invocation depends solely on the execution time of the recursive calls.
Furthermore, the only change of parameters are to parameter b and parameter e. Let us define , which is the number of elements to be considered by a particular invocation.
How does of one invocation relate to the of the recursive invocation? Let us consider all the possible cases for , which is the number of elements to consider in the recursive call:
The worst case is that .
Let us define to be the amount of time required to perform bineary search for items. Then this definition can be recursive. is the base case, in which is the upper bound of the total amount of execution time of the algorithm not counting the recursive invocations. The recursive step is because only one of the two recursive call is chosen, and the worst case is to pass elements to the next invocation.
Let us “guess” that , provided that is a power of 2. We can proof our guess as follows.
The basis: by definition. However, 0 is not a power of 2. by the recursive definition of . However, our guess also suggests that . This is the base case of the inductive proof.
The induction step states that assume for , prove that . This can be done rather easily:
Consequently, given that , binary search requires time. This means however, that because is a monotonic function that approaches as .. Because , is a tight bound for .