04.02.2018 Views

Algorithms

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

3.1 ■ Symbol Tables<br />

383<br />

Analysis of binary search The recursive implementation of rank() also leads<br />

to an immediate argument that binary search guarantees fast search, because it corresponds<br />

to a recurrence relation that describes an upper bound on the number of<br />

compares.<br />

Propos i t i o n B. Binary search in an ordered array with N keys uses no more than<br />

lg N 1 compares for a search (successful or unsuccessful).<br />

Proof: This analysis is similar to (but simpler than) the analysis of mergesort<br />

(Proposition F in Chapter 2). Let C(N) be the number of compares needed to<br />

search for a key in a symbol table of size N. We have C(0) = 0, C(1) = 1, and for N ><br />

0 we can write a recurrence relationship that directly mirrors the recursive method:<br />

C(N ) C(⎣N/2⎦) 1<br />

Whether the search goes to the left or to the right, the size of the subarray is no<br />

more than ⎣N/2⎦, and we use one compare to check for equality and to choose<br />

whether to go left or right. When N is one less than a power of 2 (say N = 2 n 1),<br />

this recurrence is not difficult to solve. First, since ⎣N/2⎦ = 2 n 1 1, we have<br />

C(2 n 1) C(2 n 1 1) 1<br />

Applying the same equation to the first term on the right, we have<br />

C(2 n 1) C(2 n 2 1) 1 1<br />

Repeating the previous step n 2 additional times gives<br />

which leaves us with the solution<br />

C(2 n 1) C(2 0 ) n<br />

C(N ) = C(2 n ) n 1 < lg N 1<br />

Exact solutions for general N are more complicated, but it is not difficult to extend<br />

this argument to establish the stated property for all values of N (see Exercise<br />

3.1.20). With binary search, we achieve a logarithmic-time search guarantee.<br />

The implementation just given for ceiling() is based on a single call to rank(), and<br />

the default two-argument size() implementation calls rank() twice, so this proof also<br />

establishes that these operations (and floor()) are supported in guaranteed logarithmic<br />

time (min(), max(), and select() are constant-time operations).

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!