Example: Printing the elements in an array
void print1(int[] ar, int size) { int i; for (i = 0; i < size; i++) System.out.println(ar[i]); } |
void print2(int[] ar, int size) { int i, j; for (i = 0; i < size; i++) { for (j = 0; j < i; j++) {} System.out.println(ar[j]); } } |
![]() |
|
Example:
2n+1 - 1
1 + 21 + 22 + .. + 2n =
---------- = 2n+1 - 1
2 - 1
Example:
1. for i := 1 to n do 2. for j := 1 to n do 3. x := x + 1 // count this line
The number of times the line 3 is executed when the input size was n:
T(n) = n + n + ... + n = n * n = n2
|<-- n of them -->|
for i := 1 to 2n do x := x + 1 // count this line
T(n) =
for i := 1 to 2n do for j := 1 to n do x := x + 1 // count this line
T(n) =
for i := 1 to n do for j := 1 to i do x := x + 1 // count this line
T(n) =
1. i := n 2. while i >= 1 do 3. begin 4. x := x + 1 // count this line 5. i := i / 2 // i becomes half 6. end
iteration value of i
(at the top of loop)number of times
line 4 is executed1 n 1 2 n/21 1 3 n/22 1 k n/2k-1 = 1 1 k+1 n/2k = 0 0
(loop not executed)
We are interested in what k is (because that's the number of times the line 4 is executed). In other words,
T(n) = 1 + 1 + 1 + .. + 1 = (k * 1)
|<-- k of them--->|To derive k, we look at the relation at the last iteration (kth):
So, T(n) = log2n + 1 (where log2n is alternatively written as lgn).
1. i := n 2. while i >= 1 do 3. begin 4. for j := 1 to n do 5. x := x + 1 // count this line 5. i := i / 2 // i becomes half 6. end
iteration | value of i (at the top of loop) |
number of times line 4 is executed |
1 | ||
2 | ||
3 | ||
k | ||
k+1 |
So, T(n)
=
= (k * ___ )
|<---- k of them ---->|
We know from example 1 that k = lgn + 1. Therefore, we get
T(n) = (k * ____) =
T(n) = 60n2 + 5n + 1
In this course, we only cover the Big-Oh. For the example above, we have:
T(n) = 60n2 + 5n + 1 = O(n2)
60n2 + 5n + 1 = O(n2) ... NOTE: f(n) = 60n2 + 5n + 1, and g(n) = n2
Proof:
1. for i := 1 to 2n do 2. x := x + 1 // count this line
1. for i := 1 to n do 2. for j := 1 to n do 3. x := x + 1 // count this line
1. for i := 1 to 2n do 2. for j := 1 to n do 3. x := x + 1 // count this line
1. for i := 1 to n do 2. for j := 1 to 2n do 3. x := x + 1 // count this line
1. for i := 1 to n do 2. for j := 1 to i do 3. x := x + 1 // count this line
1. for i := 1 to n do 2. x := x + 1 // count this line 3. for j := 1 to n do 4. for k := 1 to j do 5. y := y + 1 // count this line too
1. i := n 2. while i >= 1 do 3. begin 4. for j :=1 to n do 5. x := x + 1 // count this line 6. i := floor(i/2) 7. end
Problem: finding an element in an array of size n
Input: key, array A = [x1, x2,…, xn],
n
Output: the index of key in A, (0 if key is not in the list)
Program find_key( key, A, n ) 1. index := 1 2. while index <= n 3. begin 4. if key = A[index] then // count this comparison 5. return index 6. index := index + 1 7. end 8. return 0 end find_key
Worst-case | T(n) = _____ = O(___) |
Best-case | T(n) = _____ = O(___) |
Average-case | T(n) = _____ = O(___) |
Example: Search for 16
Problem: find an element in a sorted list (whose index is 0 through n-1)
Input: key, L a list and n
Output: The index of key in L, -1 otherwiseprocedure BinarySearch(key, L, n) 1. low := 0 2. high := n-1 3. while (low <= high) do 4. begin 5. mid = floor((low + high)/2) 6. if (key = L[mid]) then // count this comparison 7. return mid 8. else if (key < L[mid]) then 9. high := mid - 1 10. else 11. low := mid + 1 12. end 13. return -1 // key not found (fall through) end BinarySearch
The worse case occurs when key is not present is the list. How many runs through the while loop will we do?
How far can we keep dividing (what is k?)? Again, according to the algorithm we exit the loop when low > high. This means, in particular, that when we are down to 1 element and process it, we stop the loop. So,
So we get T(n) = lgn, thus O(lgn).
The best case happens when key is present at the middle of the array, namely L[n/2]. In this case, the loop executes only once, regardless of the size of array (i.e., n). So, we get T(n) = 1, thus O(1).