Unit-1 DAA Notes - Daa Unit 1 Note Unit-1 DAA Notes - Daa Unit 1 Note
Unit-1 DAA Notes - Daa Unit 1 Note Unit-1 DAA Notes - Daa Unit 1 Note
Unit-1 DAA Notes - Daa Unit 1 Note Unit-1 DAA Notes - Daa Unit 1 Note
¯
¯
lOMoARcPSD|19990856
•
lOMoARcPSD|19990856
}
Analysis
Statement Effort
InsertionSort(A, n) {
for i = 2 to n { c1n
key = A[i] c2(n-1)
j = i - 1; c3(n-1)
while (j > 0) and (A[j] > key) { c4T
A[j+1] = A[j] c5(T-(n-1))
j=j-1 c6(T-(n-1))
} 0
A[j+1] = key c7(n-1)
} 0
}
T = t2 + t3 + … + tn where ti is number of while expression evaluations for the ith for loop
iteration
T(n) = c1 n + c2(n-1) + c3(n-1) + c4T + c5(T - (n-1)) + c6(T - (n-1)) + c7(n-1) = c8T + c9n + c10
= an-b = ÷(n)
MERGE(A, p, q, r)
1 n1 ← q - p + 1
2 n2 ← r - q
Example:
Fig: The Merge procedure applies on given array and sort and combines the solution in recursive
iteration.
MERGE-SORT(A, p, r)
1 if p < r
2 then q ← (p + r)/2
3 MERGE-SORT(A, p, q)
4 MERGE-SORT(A, q + 1, r)
5 MERGE(A, p, q, r)
2 3
0 f 2n f cn Substitute
3 2 3 3 3
0/n f 2n /n f cn /n Divide by n3
Determine c
0 f 2/n f c 2/n = 0
2/n maximum when n=1
0 f 2/1 f c = 2 Satisfied by c=2
Determine n0
0 f 2/ n0 f 2
0 f 2/2 f n0
0 f 1 f n0 = 1 Satisfied by n0=1
0 f 2n2 f 2n3 ∀ n g n0=1
Big O Fact
A polynomial of degree k is O(nk)
Proof:
Suppose f(n) = bknk + bk-1nk-1 + … + b1n + b0
Let ai = | bi |
f(n) aknk + ak-1nk-1 + … + a1n + a0
i
n
n k
åai nk
nk åai cnk
We say Insertion Sort9s run time is W(n). In general a function f(n) is W(g(n)) if $ positive
constants c and n0 such that 0 £ c×g(n) £ f(n) " n ³ n0
Proof: Suppose run time is an + b. Assume a and b are positive (what if b is negative?).
an £ an + b
Example. 1. Functions in Ω(n2)
n2/ 1000, n1.999, n2+n, 1000 n2+50n
2. n3 = Ω(n2) with c=1 and n0=1
0 f cg(n) f h(n)
0 f 1*12 = 1 f 1 = 13
0 f cg(n) f h(n)
0 f c n2 f n3
0/ n2 f c n2/ n2 f n3/ n2
0fcfn
0 f 1 f 1 with c=1 and n0=1 since n increases.
ì c n=1
ï
ï
T (n) = í æ n ö
ï2T ç ÷ + cn n>1
ï
î è2ø
which looks difficult. We can simplify this recurrence, though, with a change of variables. For
convenience Renaming m= lg n yields
T(2m) = T(2m/2)+m
We can now rename S(m) = T(2m) to produce the new
recurrence S(m)= S (m/2) +m
The solution is to be S (m)= O (m lg m)
After replacing m= log n the solution becomes
T(n) = O(lg n lg lg n)
1.4.1.3 The recursion-tree method: Substitution method is not coming up with good guess.
Drawing out a recursion tree provides a method to devise a good guess. In a recursion tree, each
node represents the cost of a single subproblem somewhere in the set of recursive function
invocations. We sum the costs within each level of the tree to obtain a set of per-level costs, and
then we sum all the per-level costs to determine the total cost of all levels of the recursion.
For example, let us see how a recursion tree would provide a good guess for the recurrence
T(n)= 3T( n/4 ) + ÷(n2)
we create a recursion tree for the recurrence T(n)= 3T(n/4) + cn2, having written out the implied
constant coefficient c > 0.
Fig: Constructing a recursion tree for the recurrence T(n)= 3T(n/4) + cn2. Part (a) shows T (n),
which progressively expands in (b)–(d) to form the recursion tree. The fully expanded tree in
part (d) has height log4n (it has log4n +1 levels).
The above fig shows how we derive the recursion tree for T(n)= 3T(n/4) + cn2 .For convenience,
we assume that n is an exact power of 4 so that all subproblem sizes are integers. Part (a) of the
figure shows T(n), which we expand in part (b) into an equivalent tree representing the
recurrence. The cn2 term at the root represents the cost at the top level of recursion, and the three
subtrees of the root represent the costs incurred by the subproblems of size n=4. Part (c) shows
this process carried one step further by expanding each node with cost T(n/4) from part (b). The
cost for each of the three children of the root is c(n/42). We continue expanding each node in the
tree by breaking it into its constituent parts as determined by the recurrence.
Because subproblem sizes decrease by a factor of 4 each time the subproblem size for a node at
depth i is (n/4i). Thus for subproblem size at last level n=1 n/4i =1 then i = log4n and the tree has
log4n+1 levels. The cost of each node is derived by generalized term at depth i where i= 0, 1,
2…….log4n-1 by c (n/4i)2 . the total cost over all nodes at depth i, for i= 0, 1, 2…….log4n-1 is 3i
(n/4i )2 =(3/16)i cn2. The last level i.e. at depth log4n cost is 3log4n= nlog43 nodes each contributing
cost T(1), for a total cost nlog43 T(1) which is ÷(nlog43 ) since we assume T(1) is constant.
Now we add up the costs over all levels to determine the cost for the entire tree:
Thus, we have derived a guess of T(n)= O(n2). Now we can use the substitution method to verify
that our guess was correct, that is, T(n)= O(n2) is an upper bound for the recurrence T(n)= 3T(
n/4 ) + ÷(n2). We want to show that T(n)f dn2 for some constant d > 0. Using the same constant
c > 0 as before, we have
Let ag1and b>1 be constants, let f (n) be a function, and let T(n) be defined on the nonnegative
integers by the recurrence
T(n) = a T(n/b) + f(n)
where we interpret n/b to mean either floor (n/b) or ceil (n/b). Then T(n) has the following
asymptotic bounds:
1. If f (n) = O(nlog a− ) for some constant ø>0 then T(n)= (nlog
b b
a
(
2. If f (n) = nlogb a ) ). then T(n)= ÷(nlogba log n).
3. If f (n) = (nlog a+ ) for some constant ø>0 and if a T (n/b) fc f(n)(regularity function)
b
for some constant c<1 and all sufficiently large n then T(n)= ÷(f (n)).
In each of the three cases, we compare the function f (n) with the function nlogba. Intuitively, the
larger of the two functions determines the solution to the recurrence. In case 1the function nlogba
( )
is larger, solution is T(n)= nlogb a . In case 3 function f(n) is larger, solution is T(n)= ÷(f (n)).
In case 2 both functions has same value, solution is T(n)= ÷(nlogba log n).
In the first case, not only must f(n) be smaller than n logba, it must be polynomially smaller. In
the third case, not only must f (n) be larger than nlogba , it also must be polynomially larger and
in addition satisfy the <regularity= condition that a T (n/b) fc f(n). An addition to that all three
cases do not cover all possibilities. Some function might be lies in between case 1 and 2 and
some other lies in between case 2 and 3 because the comparison is not polynomial larger or
smaller and in case 3 the regularity condition fails.
Example. 1. . The given recurrence is
T(n) = 9T(n/3) + n
Sol: a=9, b=3, f(n) = n
nlogb a = nlog3 9 = (n2)
Since f(n) = O(nlog3 9 - ), where =1, case 1 applies:
(
T (n) = nlogb a ) when f (n) = O(nlog a− ) b
2. T(n)= T(2n/3)+1
in which a = 1, b= 3/2, f(n)= 1, and nlogba = nlog3/2 =n0 = 1. Case 2
applies, since f (n)= (nlogba )= (1) and thus the solution to the recurrence is T(n) =(lg n)
3. The master method does not apply to the recurrence:
T(n)= 2T(n/2) +n log n
Sol: a=2, b=2, f(n)= n log n , nlogba=nlog 2=n
Since f(n) is larger than nlogba you mistakenly apply case 3 but the f(n) is larger but not
polynomialy larger. The ratio f(n)/ nlogb a= log n is asymptotically less than nø for any positive
constant ø. Consequently, the recurrence falls into the gap between case 2 and case 3.
An array A that represents a heap is an object with two attributes: A.length, which (as usual)
gives the number of elements in the array, and A.heap-size, which represents how many
elements in the heap are stored within array A. That is, although A (1……..A.length) may
Parent(i)
return floor (i/2)
Left(i)
return 2i
Right(i)
return 2i+1
There are two kinds of binary heaps: max-heaps and min-heaps. In both kinds, the values in the
nodes satisfy a heap property, the specifics of which depend on the kind of heap. In a max-heap,
the max-heap property is that for every node i other than the root,
A[parent(i)]gA[i]
That is the value of a node is lesser or equal to parent.
A min-heap is organized in the opposite way; the min-heap property is that for every node i other
than the root,
A[parent(i)]fA[i]
For the heapsort algorithm, we use max-heaps.
Figure: The action of MAX-HEAPIFY(A, 2), where heap-size[A] = 10. (a) The initial
configuration, with A[2] at node i = 2 violating the max-heap property since it is not larger than
both children. The max-heap property is restored for node 2 in (b) by exchanging A[2] with A[4],
which destroys the max-heap property for node 4. The recursive call MAXHEAPIFY( A, 4) now
has i = 4. After swapping A[4] with A[9], as shown in (c), node 4 is fixed up, and the recursive
call MAX-HEAPIFY(A, 9) yields no further change to the data structure.
1.5.1.2 Complexity
We can describe the running time of MAX-HEAPIFY by the
recurrence T(n)f2T(n/3)+÷(1)
The solution to this recurrence, by case 2 of the master theorem is T(n)= O(lg n)
1.5.2.1 BUILD-MAX-HEAP(A)
1. A.heap-size = A.length
2. for i = ëlength[A]/2û downto 1
3. MAX-HEAPIFY(A, i)
The time required by MAX-HEAPIFY when called on a node of height h is O(h), the running
time of above algorithm is O(n).
Figure: The operation of BUILD-MAX-HEAP, showing the data structure before the call to
MAX-HEAPIFY in line 3 of BUILD-MAX-HEAP. (a) A 10- element input array A and the
binary tree it represents. The figure shows that the loop index i refers to node 5 before the call
MAX-HEAPIFY(A, i). (b) The data structure that results. The loop index i for the next iteration
refers to node 4. (c)-(e) Subsequent iterations of the for loop in BUILD-MAXHEAP. Observe
that whenever MAX-HEAPIFY is called on a node, the two subtrees of that node are both max-
heaps. (f) The max-heap after BUILD-MAX-HEAP finishes.
1.5.3.1 HEAPSORT(A)
1. BUILD-MAX-HEAP(A)
2. for i = length(A) downto 2
3. Exchange (A[1] with A[i]);
4. A.heap-size= A.heap-size -1;
5. MAX-HEAPIFY (A, 1);
Figure: The operation of HEAPSORT. (a) The max-heap data structure just after it has been built
by BUILD -MAX-HEAP. (b)-(j) The max-heap just after each call of MAXHEAPIFY in line 5.
The value of i at that time is shown. Only lightly shaded nodes remain in the heap. (k) The
resulting sorted array A.
3. QUICKSORT(A, p, q)
4. QUICKSORT(A, q+1, r)
To sort an entire array A, the initial call is QUICKSORT (A, 1, A.length).
Figure: The operation of PARTITION on a sample array. Lightly shaded array elements are all in
the first partition with values no greater than x. Heavily shaded elements are in the second
partition with values greater than x. The unshaded elements have not yet been put in one of the
first two partitions, and the final white element is the pivot. (a) The initial array and variable
settings. None of the elements have been placed in either of the first two partitions. (b) The value
2 is "swapped with itself" and put in the partition of smaller values. (c)-(d) The values 8 and 7
are added to the partition of larger values. (e) The values 1 and 8 are swapped, and the smaller
partition Grows. (f) The values 3 and 8 are swapped, and the smaller partition grows. (g)-(h) The
larger partition grows to include 5 and 6 and the loop terminates. (i) In lines 7-8, the pivot
element is swapped so that it lies between the two par titions.
{
a[j] = a[j - gap]
}
# put temp (the original a[i]) in its correct
location a[j] = temp
}
The first pass, 5-sorting, performs insertion sort on separate subarrays (a1, a6, a11), (a2, a7, a12), (a3,
a8), (a4, a9), (a5, a10). For instance, it changes the subarray (a1, a6 , a11) from (62, 17, 25) to (17,
25, 62). The next pass, 3-sorting, performs insertion sort on the subarrays (a1, a4, a7, a10),
(a2, a5, a8, a11), (a3, a6, a9, a12). The last pass, 1-sorting, is an ordinary insertion sort of the
entire array (a1,..., a12).
The complexity of this algorithm is O (n1.25).
COUNTING-SORT(A, B, k)
1 for i ← 0 to k
2 do C[i] ← 0
3 for j ← 1 to length[A]
4 do C[A[j]] ← C[A[j]] + 1
5 //C[i] now contains the number of elements equal to i.
6 for i ← 1 to k
7 do C[i] ← C[i] + C[i - 1]
8 //C[i] now contains the number of elements less than or equal to i.
9 for j ← length[A] downto 1
10 do B[C[A[j]]] ← A[j]
11 C[A[j]] ← C[A[j]] 3 1
Figure: The operation of COUNTING-SORT on an input array A[1,…..., 8], where each element
of A is a nonnegative integer no larger than k = 5. (a) The array A and the auxiliary array C after
line 4. (b) The array C after line 7. (c)-(e) The output array B and the auxiliary array C after one,
two, and three iterations of the loop in lines 9-11, respectively. Only the lightly shaded elements
of array B have been filled in. (f) The final sorted output array B.
Figure: The operation of radix sort on a list of seven 3-digit numbers. The leftmost column is the
input. The remaining columns show the list after successive sorts on increasingly significant digit
positions. Shading indicates the digit position sorted on to produce each list from the previous
one.
Example:
Figure: The operation of BUCKET-SORT for n= 10. (a) The input array A(1……..10). (b) The
array B(0…… 9) of sorted lists (buckets) after line 8 of the algorithm. Bucket i holds values in
the half-open interval [i/10,.i + 1/10). The sorted output consists of a concatenation in order of
the lists B[0], B[1]…….B[9]
To analyze the running time, observe that all lines except line 5 take O (n) time in the worst case.