# L-15 MCS 275 Mon 15 Feb 2010 : binarysearch.py # # Searches a number in a sorted list of integer numbers. # The builtin "in" operator on list does not take # into account that the list is sorted. from random import randint def LinearSearch(L,x): """ Returns -1 if x belongs to L, else returns k for which L[k] == x. Items in the list L must be sorted in increasing order. """ for i in range(0,len(L)): if L[i] == x: return i elif L[i] > x: return -1 return -1 def BinaryIsIn(L,x): """ Applies binary search to check whether x is in the sorted list L. Returns True if x is in L, otherwise False is returned. """ if len(L) == 0: return False elif len(L) == 1: return (L[0] == x) else: m = len(L)/2 if L[m] == x: return True elif L[m] > x: return BinaryIsIn(L[0:m],x) else: return BinaryIsIn(L[m+1:len(L)],x) def BinaryIsInTrace(L,x,k): """ Traces binary search to check whether x is in the sorted list L. Returns True if x is in L, otherwise False is returned. """ s = k*' ' + 'find ' + str(x) print s + ' in L = ' + str(L) if len(L) == 0: return False elif len(L) == 1: return (L[0] == x) else: m = len(L)/2 if L[m] == x: return True elif L[m] > x: return BinaryIsInTrace(L[0:m],x,k+1) else: return BinaryIsInTrace(L[m+1:len(L)],x,k+1) def BinarySearch(L,x): """ Applies binary search to find the position k of x in the sorted list L. Returns -1 if not x in L, or else returns k for which L[k] == x. """ if len(L) == 0: return -1 elif len(L) == 1: if L[0] == x: return 0 else: return -1 else: m = len(L)/2 if L[m] == x: return m elif L[m] > x: return BinarySearch(L[0:m],x) else: k = BinarySearch(L[m+1:len(L)],x) if k == -1: return -1 return k + m + 1 def main(): """ Illustration of linear and binary search in a sorted list of numbers. Prompts the user for the bounds of [a,b] and N because the list will contain N numbers uniformly distributed in [a,b]. """ a = input('Give lower bound : ') b = input('Give upper bound : ') N = input('How many numbers ? ') r = lambda i: randint(a,b) L = map(r,range(0,N)) L.sort() print 'L =', L while True: x = input('Give number to search for : ') c = x in L # sanity check if c: i = L.index(x) d = BinaryIsIn(L,x) e = BinaryIsInTrace(L,x,0) kl = LinearSearch(L,x) kb = BinarySearch(L,x) if kb == -1: print x, 'does not occur in L', not c, not d, kl == kb else: print 'L[%d] = %d = %d = %d' % (kb,L[kb],L[i],L[kl]), c, d ans = raw_input('Search for more ? (y/n) ') if ans != 'y': break main()