Design and Analysis of Algorithms: Israr Ali
Design and Analysis of Algorithms: Israr Ali
Algorithms
Presented By:
Israr Ali
Properties
• c1 < c2, but constants less significant in the running time than the
input size.
• lg n < n, but insertion sort is usually faster than merge sort for small
input sizes.
• Once the input size n becomes large enough, merge sort will become
faster than insertion sort.
Algorithm efficiency
Example:
Computer A executes one billion instruction per second (1 GHz) and
executes insertion sort (c1n2).
Computer B executes one million instruction per second (1 MHz) and
executes merge sort (c2 n lg n).
Assume c1=2 and c2=50.
Assume we need to sort 1 million numbers.
Algorithm efficiency
• We analyze algorithms to improve them and choose the best one for
a given problem.
Algorithm Questions
40 2 1 43 3 65 0 -1 58 3 42 4
2 40 1 43 3 65 0 -1 58 3 42 4
1 2 40 43 3 65 0 -1 58 3 42 4
Insertion Sort: Example
1 2 40 43 3 65 0 -1 58 3 42 4
1 2 3 40 43 65 0 -1 58 3 42 4
1 2 3 40 43 65 0 -1 58 3 42 4
Insertion Sort: Example
1 2 3 40 43 65 0 -1 58 3 42 4
0 1 2 3 40 43 65 -1 58 3 42 4
-1
0 1
0 2
1 3
2 40
3 40
43 43
65 65 58 3 42 4
Insertion Sort: Example
-1
0 1
0 2
1 3
2 40
3 40
43 43
65 58 65 3 42 4
-1
0 1
0 2
1 3
2 40
3 43
3 40
65 43
43 58 58
65 65 42 4
-1
0 1
0 2
1 3
2 40
3 43
3 40
65 42 43
43 65 58 65 4
-1
0 1
0 2
1 3
2 40
3 43
3 43
65
4 40
42 42
65 43
43 58 58
65 65
Insertion sort – pseudo code
• InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j=j-1
}
A[j+1] = key
}
}
An Example: Insertion Sort
30 10 40 20 i = j = key =
A[j] = A[j+1] =
1 2 3 4
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
David Luebke
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
David Luebke
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
David Luebke
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
David Luebke
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
David Luebke
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
David Luebke
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
David Luebke
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
David Luebke
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
David Luebke
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
David Luebke
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
David Luebke
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
David Luebke
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
David Luebke
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
David Luebke
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
David Luebke
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
David Luebke
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
David Luebke
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
David Luebke
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
David Luebke
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
David Luebke
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
David Luebke
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
David Luebke
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
David Luebke
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
David Luebke
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
David Luebke
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
David Luebke
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
David Luebke
An Example: Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
}
}
Done!
David Luebke
Loop invariants and Correctness
David Luebke
Insertion Sort
InsertionSort(A, n) {
for i = 2 to n {
key = A[i]
j = i - 1;
while (j > 0) and (A[j] > key) {
A[j+1] = A[j]
j = j - 1
}
A[j+1] = key
} How many times will
} this loop execute?
David Luebke
Loop Invariants
Invariant
• At the start of each iteration of the for loop of lines 1–8, the sub-array A[1 .. j-1] consists of
the elements originally in A[1 .. j-1] , but in sorted order.
• Initialization
• Maintenance:
• the loop moves the A[1 .. j-2] .. Elements to the right until it finds a suitable
place for A[j]. The sub-array A[1 .. j] then consists of the elements originally in
A[1 .. j] , but in sorted order
• Termination
• In the end we have j = n +1, substitute this in the “invariant” wording
Analysis Insertion Sort
David Luebke
To compute T (n), the running time of INSERTION-SORT on an input of n
values, we sum the products of the cost and times columns, obtaining
• best-case running time is
We can express this running time as (an + b) for constants a and b that
depend on the statement costs c ; it is thus a linear function of n
i
• If the array is in reverse sorted order that is, in decreasing order the worst case results
We can express this worst-case running time as (an2 + bn + c) for
constants a, b, and c that again depend on the statement costs c ; it is
i
David Luebke
Designing algorithms
•Mergesort (divide-and-conquer)
• Divide array into two halves.
A L G O R I T H M S
A L G O R I T H M S divide
Mergesort
•Mergesort (divide-and-conquer)
• Divide array into two halves.
• Recursively sort each half.
A L G O R I T H M S
A L G O R I T H M S divide
A G L O R H I M S T sort
Mergesort
•Mergesort (divide-and-conquer)
• Divide array into two halves.
• Recursively sort each half.
• Merge two halves to make sorted whole.
A L G O R I T H M S
A L G O R I T H M S divide
A G L O R H I M S T sort
A G H I L M O R S T merge
Merging
•Merge.
• Keep track of smallest element in each sorted half.
• Insert smallest of two elements into auxiliary array.
• Repeat until done.
smallest smallest
A G L O R H I M S T
A auxiliary array
Merging
•Merge.
• Keep track of smallest element in each sorted half.
• Insert smallest of two elements into auxiliary array.
• Repeat until done.
smallest smallest
A G L O R H I M S T
A G auxiliary array
Merging
•Merge.
• Keep track of smallest element in each sorted half.
• Insert smallest of two elements into auxiliary array.
• Repeat until done.
smallest smallest
A G L O R H I M S T
A G H auxiliary array
Merging
•Merge.
• Keep track of smallest element in each sorted half.
• Insert smallest of two elements into auxiliary array.
• Repeat until done.
smallest smallest
A G L O R H I M S T
A G H I auxiliary array
Merging
•Merge.
• Keep track of smallest element in each sorted half.
• Insert smallest of two elements into auxiliary array.
• Repeat until done.
smallest smallest
A G L O R H I M S T
A G H I L auxiliary array
Merging
•Merge.
• Keep track of smallest element in each sorted half.
• Insert smallest of two elements into auxiliary array.
• Repeat until done.
smallest smallest
A G L O R H I M S T
A G H I L M auxiliary array
Merging
•Merge.
• Keep track of smallest element in each sorted half.
• Insert smallest of two elements into auxiliary array.
• Repeat until done.
smallest smallest
A G L O R H I M S T
A G H I L M O auxiliary array
Merging
•Merge.
• Keep track of smallest element in each sorted half.
• Insert smallest of two elements into auxiliary array.
• Repeat until done.
smallest smallest
A G L O R H I M S T
A G H I L M O R auxiliary array
Merging
•Merge.
• Keep track of smallest element in each sorted half.
• Insert smallest of two elements into auxiliary array.
• Repeat until done.
first half
exhausted smallest
A G L O R H I M S T
A G H I L M O R S auxiliary array
Merging
•Merge.
• Keep track of smallest element in each sorted half.
• Insert smallest of two elements into auxiliary array.
• Repeat until done.
first half
exhausted smallest
A G L O R H I M S T
A G H I L M O R S T auxiliary array
Merge Sort - Example
Merge sort – Merge procedure
Invariants of Merge Procedure
At the start of each iteration of the for loop of lines 12–17, the sub-array A[p..k-1]
contains the k -p smallest elements of L[1 .. N1+1] and R[1 .. N2+1], in sorted order.
Moreover, L[i] and R[j] are the smallest elements of their arrays that have not been
copied back into A.
• Initialization: Prior to the first iteration of the loop, we have k = p, so
that the sub-array A[p..k-1] is empty.
• Maintenance
• Termination
Merge Sort procedure
Analyzing divide-and-conquer algorithms
• recurrence equation or recurrence, which describes the overall
running time on a problem of size n in terms of the running time on
smaller inputs.
• Suppose that our division of the problem yields ‘a’ sub-problems,
each of which is ‘1/b’ the size of the original.
• It takes time T (n/b) to solve one sub-problem of size n=b, and so it
takes time ‘a T (n/b)’ to solve ‘a’ of them.
• D(n) : time to divide, C(n) : time to combine
Analysis of merge sort
• Divide: The divide step just computes the middle of the sub-array,
which takes constant time. Thus, D(n) = Θ(1).
• Conquer: We recursively solve two sub-problems, each of size n=2,
which contributes 2T(n/2) to the running time.
• Combine: The combine step also takes constant time. Thus, C(n) =
Θ(1).