Divide & Conquer - Binary Search Divide-and-Conquer The most-well known algorithm design strategy: 1. Divide instance of problem into two or more smaller instances of same size. 2.Solve smaller instances recursively. 3.Obtain solution to original (larger) instance by combining these solutions. Divide-and-Conquer Technique (cont.) a problem of size n subproblem 1 of size n/2 subproblem 2 of size n/2 a solution to subproblem 1 a solution to subproblem 2 a solution to the original problem Divide-and-Conquer Examples • Sorting: mergesort and quicksort • Binary tree traversals • Binary search • Multiplication of large integers • Matrix multiplication: Strassen’s algorithm • Closest-pair and convex-hull algorithms General Divide-and-Conquer Recurrence T(n) = aT(n/b) + f (n) where f(n) (nd), d 0 Master Theorem: If a < bd, T(n) (nd) If a = bd, T(n) (nd log n) If a > bd, T(n) (nlog b a ) Note: The same results hold with O instead of . Examples: T(n) = 4T(n/2) + n T(n) ? T(n) = 4T(n/2) + n2 T(n) ? T(n) = 4T(n/2) + n3 T(n) ? Binary Search • Binary search is an efficient algorithm for searching in a sorted array. • It works by comparing a search key K with the array’s middle element A[m]. • If they match, the algorithm stops; otherwise, the same operation is repeated recursively for the first half of the array if K<A[m] and for the second half if K>A[m]: Binary Search Binary Search Binary Search Algorithm Algorithm: bin-search(A[0…n-1], l, r, k) //Input: Array A of size n, left index l, right index r and search key k //output: index l if search key is found and -1 otherwise If l = = r If k = = A[l] then return l else return -1; else int mid = (l+ r)/2; if k > A[mid] return bin-search(A, mid+1, r); else return bin-search(A, l, mid); end if end if Binary Search • Input size – n. • Basic operation - comparison • The worst-case inputs include all arrays that do not contain a given search key, as well as some successful searches. Worst-case Analysis • • • • Item not in the array (size N) T(N) = number of comparisons with array of N elements T(N) = 1 + T(N / 2) T(1) = 1 // Initial condition from base case Worst-case Analysis • • • • Item not in the array (size N) T(N) = number of comparisons with array elements T(1) = 1 T(N) = 1 + T(N / 2) = 1 + [1 + T(N / 4)] Worst-case Analysis • • • • Item not in the array (size N) T(N) = number of comparisons with array elements T(1) = 1 T(N) = 1 + T(N / 2) = 1 + [1 + T(N / 4)] = 2 + T(N / 4) = 2 + [1 + T(N / 8)] Worst-case Analysis • • • • Item not in the array (size N) T(N) = number of comparisons with array elements T(1) = 1 T(N) = 1 + T(N / 2) = 1 + [1 + T(N / 4)] = 2 + T(N / 4) = 2 + [1 + T(N / 8)] = 3 + T(N / 8) =… Worst-case Analysis • • • • Item not in the array (size N) T(N) = number of comparisons with array elements T(1) = 1 T(N) = 1 + T(N / 2) = 1 + [1 + T(N / 4)] = 2 + T(N / 4) = 2 + [1 + T(N / 8)] = 3 + T(N / 8) =… = k + T(N / 2k ) [1] Worst-case Analysis • T(N) = k + T(N / 2k ) [1] • Substitute value for k such that eqn 1 becomes T(1) Take 2k = N k = log2N • Replace terms with k in [1]: T(N) = log2N + T(N / N) = log2N + T(1) = log2N + 1 • So time complexity is O(log2N)