Professional Documents
Culture Documents
ALGS Class3y4
ALGS Class3y4
Iterative Algorithms
GENERIC-ITERATION1
1 Initialization
2 repeat
3 Progression
4 until Stopping-Condition
GENERIC-ITERATION2
1 Initialization
2 while not Stopping-Condition
3 Progression
GENERIC-ITERATION3
1 Initialization
2 if not Stopping-Condition
3 Progression
4 else Go To 2
Example
FINDMAX1(A)
1 max ← −∞ // Initialize max
2 i←1
3 while i ≤ A.length
4 if A[i] > max // Update max if necessary
5 max ← A[i]
6 i ←i+1
7 return (max )
FINDMAX2(A)
1 max ← −∞ // Initialize max
2 for i ← 1 to A.length
3 if A[i] > max // Update max if necessary
4 max ← A[i]
5 return (max )
Loop Invariants
I Loop invariants help us understand why an algorithm is correct.
precondition postcondition
of the loop of the loop
and
initialization
establishes
stopping
invariant
condition
and
not
progression
preserves
FINDMAX(A)
1 max ← −∞
An introductory example: the Euclidian division
2 for i ← 1 to A.length
consider
3 the if
classical
A[i] > problem
max of
// the Euclidian
Update max division. We are interested in the calc
if necessary
on of the quotient of the “integer” division of A by B (A 2 N, B 2 N1 ), knowing that w
4 max ← A[i]
not provided with a division operation. The specification of the program to design
en by5 thereturn
pair: (max )
condition: (A 2 N) and (B 2 N1 ).
Loop Invariant:
stcondition: q is the quotient and r is the remainder of the division of A by B.
At the start of each iteration of the for loop of lines 2-4, the variable
In order
max to
is make
equalthe postcondition
to the maximum“usable”
entry in(this point willAbe
the subarray [1 developed
: i − 1] later), it
ormulated on the basis of the definition of the Euclidian division by:
(A = B · q + r) and (0 6 r)
Sorting
d as stopping condition: r < B. The actions related to the progression and the initializ
n remain
Input: Anexpressed,
to be array A ofas well as
length n the termination expression. As to the progressio
uffices to increment q of 1 and to decrement r of the value of B to restore the invaria
hich is possible since the stopping condition is not met, hence r > B). The invariant
Output:
ablished from the A ordered copy Bbyofthe
precondition array A, that0is,tofor
theassignments: some
q and A permutation
to r. Concerning th
mination
i0 , i1 ,expression,
. . . , in−1 ofit0,can
1, . be n − 1, it holds
. . ,observed that the expression (A - q · B) is equal to
that
er the initialization takes place and diminishes of B whilst being positive after each ste
(1) A[j] = B[ij ] for j = 0, . . . , n − 1
(2) B[0] ≤ B[1] ≤ · · · ≤ B[n − 1]
Insertion-Sort
I The idea is to iteratively sort the initial subarray adding one more
element in each iteration
I In the ith step, the next element A[i] is inserted into the previous
subarray A[1 . . i − 1] which is already sorted
I The method is not very efficient, its running time is O(n2 ) while
faster algorithms sort in time O(n log n).
Recursive version
INSERTION-SORT(A, n)
1 if n = 1 return
2 INSERTION-SORT(A, n − 1)
3 INSERTLAST(A, n)
INSERTLAST(A, n)
1 // Insert A[n] into the sorted sequence A[1 . . n − 1]
2 if n = 1 return
3 if A[n − 1] > A[n]
4 A[n − 1] ↔ A[n]
5 INSERTLAST(A, n − 1)
Iterative Version
I each iteration of the outer loop (for) adds the next element
INSERTION-SORT(A)
1 for j ← 2 to A. length
2 // Insert A[j] into the sorted sequence A[1 . . j − 1]
3 i ←j−1
4 while i > 0 and A[i] > A[i + 1]
5 A[i] ↔ A[i + 1]
6 i ←i−1
INSERTION-SORT(A)
1 for j ← 2 to A. length
2 key ← A[j]
3 // Insert A[j] into the sorted sequence A[1 . . j − 1]
4 i ←j−1
5 while i > 0 and A[i] > key
6 A[i + 1] ← A[i]
7 i ←i−1
8 A[i + 1] ← key
Initialization:
I In the first iteration, j = 2 and then A[1 . . j − 1] = A[1] which is the
original A[1] and it is trivially sorted.
Maintenance:
I Steps 2 places the next item A[j] in the temporary variable key and
step 3 initializes i to j − 1.
I From the termination analysis for the inner while loop in lines 5-7
the sorted subarray A[1 . . i] is unmodified and all its elements are
smaller than or equal than key, and
I the sorted subarray A[i + 1 . . j − 1] has been shifted one position to
A[i + 2 . . j] and all of its elements are larger than key.
1 i i+1 j−1 j
1 i i+1 i+2 j
I Thus, step 8 places key which contains the original A[j] into the
correct place so that now the subarray A[1 . . j] consists of the elements
originally in A[1 . . j] but in sorted order.
Termination: The loop terminates when j takes the value A. length + 1.
By the invariant then A is the initial array but sorted.
I From the invariant of the outer for loop, before the execution of the
inner while loop, the subarray A[1 . . j − 1] consists of the elements
originally in A[1 . . j − 1] in sorted order and the subarray A[j . . n] has
not been modified.
I From the instructions 2 and 4 before the while key contains the
original element A[j] and i has been initialized to j − 1.
INSERTION-SORT(A)
1 for j ← 2 to A. length
2 key ← A[j]
3 // Insert A[j] into the sorted sequence A[1 . . j − 1]
4 i ←j−1
5 while i > 0 and A[i] > key
6 A[i + 1] ← A[i]
7 i ←i−1
8 A[i + 1] ← key
1 i i+1 j−1 j
1 i i+1 i+2 j
Initialization:
In the first iteration, i = j − 1 and then A[1 . . i] is A[1 . . j − 1] and
A[i + 1 . . j − 1] is an empty subarray. Thus, the invariant holds.
Maintenance:
In an iteration of the loop the conditions i > 0 and A[i] > key hold and
in lines 6-7 A[i] is shifted to position A[i + 1] and i is decremented by 1,
and so the invariant holds at the beginning of the next iteration.
Termination:
The loop terminates when either i = 0 or A[i] ≤ key.
I If i = 0 then the initial A[1 . . j − 1] subarray has been shifted to
A[2 . . j] and all of its elements are larger than key and so the correct
sorted position for key is A[1] as done in line 8.
I If A[i] ≤ key then the correct sorted position for key is A[i + 1] as
done in line 8.
Merge-Sort
Divide: The array is split into two halves, the left and right parts.
Conquer: Each half is sorted recursively
Combine: The two sorted halves are merged into a single sorted array
Basis of recursion: The recursion "bottoms out” –it reaches the base
case – when the subarray to be sorted has just 1 element
Pseudocode
MERGE-SORT(A, p, r )
1 if p ≥ r // zero or one element?
2 return
3 q ← b(p + r )/2c // midpoint of A[p . . r ]
4 MERGE-SORT(A, p, q) // recursively sort A[p . . q]
5 MERGE-SORT(A, q + 1, r ) // recursively sort A[q + 1 . . r ]
6 MERGE(A, p, q, r ) // Merge A[p . . q] and A[q + 1 . . r ] into A[p . . r ]
MERGE(A, p, q, r )
1 nL ← q − p + 1 // length of A[p : q]
2 nR ← r − q // length of A[q + 1 : r ]
3 let L[0 : nL − 1] and R[0 : nR − 1] be new arrays
4 for i ← 0 to nL − 1 // copy A[p : q] into L[0 : nL − 1]
5 L[i] ← A[p + i]
6 for j ← 0 to nR − 1 // copy A[q + 1 : r ] into R[0 : nR − 1]
7 R[j] ← A[q + 1 + j]
8 i←0 // i indexes smallest remaining element in L
9 j←0 // j indexes smallest remaining element in L
10 k←p // k indexes location in A to fill
11 while i < nL and j < nR
12 if L[i] ≤ R[j] //
13 A[k] ← L[i] // As long as each of the arrays L and R
14 i ←i+1 // contains an unmerged element, copy
15 else A[k] ← R[j] // the smallest unmerged element back
16 j ←j+1 // into A[p : r ].
17 k ←k+1 //
18 while i < nL
19 A[k] ← L[i] //
20 i ←i+1 // Having gone through one of L and R
21 k ←k+1 // entirely, copy the remainder of the other
22 while j < nR // to the end of A[p : r ].
23 A[k] ← R[j] //
24 j ←j+1 //
25 k ←k+1
I The while loop of lines 11-17 repeatedly identifies the smallest value
in L and R that has yet to be copied back into A[p : r ] and copies it back
in
I The index k gives the position of A that is being filled in, and the
indices i and j give the positions in L and R, respectively, of the smallest
remaining values
Merging Example
T (n) = 2T (n/2) + Cn
T (n) = 2T (n/2) + Cn
= 2(2T ((n/2)/2) + C(n/2)) + Cn
= 22 T (n/22 ) + C2n
= 22 (2T ((n/22 )/2) + C(n/22 )) + C2n
= 23 T (n/23 ) + C3n
..
.
= 2i T (n/2i ) + Cin
..
.
= 2k T (n/2k ) + Ckn
= nT (1) + Ckn
= Dn + Cn log2 n
= O(n log n).
Quick-Sort
Divide: A pivot is selected and the array is split into two parts, the
entries smaller than or equal to the pivot and the entries larger than
the pivot
Conquer: Each half is sorted recursively
Combine: The two sorted parts are simply concatenated
Basis of recursion: The recursion "bottoms out” –it reaches the base
case – when the subarray to be sorted has just 1 element
Pseudocode
QUICK-SORT(A, p, r )
1 if p < r
2 q ← PARTITION(A, p, r )
3 QUICK-SORT(A, p, q)
4 QUICK-SORT(A, q + 1, r )
PARTITION(A, p, r )
1 pivot ← A[r ]
2 i ←p−1
3 for j ← p to r − 1
4 if A[j] ≤ pivot
5 i ←i+1
6 A[i] ↔ A[j]
7 A[i + 1] ↔ A[r ]
8 return i + 1
Invariant
Maintenance
Running Time
Selection-Sort
1 for i ← 1 to A.length − 1
2 // find the min element in the unsorted A[i . . A.length]
3 jMin ← i
4 for j ← i + 1 to A.length
5 if A[j] < A[jMin]
6 jMin ← j
7 // place min element in A[i]
8 if jMin 6= i
9 A[i] ↔ A[jMin]
Heap-Sort
Binary Search
Correctness of BINARYSEARCH:
Each iteration of the while loop of lines 2–8
either finds key in A[mid] and returns the index mid in line 5 or
it reduces the search subarray from A[left . . right] to the “half”
subarray A[left0 . . right0 ] which may contain key:
it is A[left . . mid − 1] if key < A[mid] (line 8) or
A[mid + 1 . . right] if key > A[mid] (line 7).
The discarded half cannot contain key.
Also, because of the choice of mid, we have that
right − left + 1
0 0
right − left + 1 ≤ , (∗)
2
with equality in the worst case; so if key is not found then eventually
the condition left ≤ right no longer holds and so the while loop is
exited, and −1 returned in line 9.
Number of times the array is halved: According to (∗), a subarray of
length n is reduced to bn/2c in the worst case. If
2k−1 ≤ n < 2k
k − 1 ≤ log n < k,