Algorithm design problem set
LE/EECS3101
Design and Analysis of Algorithms
Iterative Algorithms & Loop Invariants – Insertion Sort
Karim Jahed
Insertion Sort
1 fun i n s e r t i o n S o r t (A [ 1 . . n ] )
2 for j = 2 to n
3 key = A[ j ]
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
Insertion Sort
1 fun i n s e r t i o n S o r t (A [ 1 . . n ] )
2 for j = 2 to n
3 i n v a r i a n t LI1: A[1..j-1] is sorted
4 key = A[ j ]
5 i = j − 1 6 while i > 0 and A[ i ] > key
7 A[ i + 1] = A[ i ]
8 i = i − 1 9 A[ i + 1] = key
10 postcond A[1..n] is sorted
1
Insertion Sort
1 fun i n s e r t i o n S o r t (A [ 1 . . n ] )
2 for j = 2 to n
3 i n v a r i a n t LI1: A[1..j-1] is sorted
4 key = A[ j ]
5 i = j − 1 6 while i > 0 and A[ i ] > key
7 A[ i + 1] = A[ i ]
8 i = i − 1 9 postcond Every element in A[i+1..j] is ≥ key
10 A[ i + 1] = key
11 postcond A[1..n] is sorted
1
Insertion Sort
1 fun i n s e r t i o n S o r t (A [ 1 . . n ] )
2 for j = 2 to n
3 i n v a r i a n t LI1: A[1..j-1] is sorted
4 key = A[ j ]
5 i = j − 1 6 while i > 0 and A[ i ] > key
7 i n v a r i a n t LI2: every element in A[i..j] is ≥ key 8 A[ i + 1] = A[ i ]
9 i = i − 1 10 postcond Every element in A[i+1..j] is ≥ key 11 A[ i + 1] = key
12 postcond A[1..n] is sorted
1
Proof of LI2
LI2: ‘At the beginning of the ith iteration, every element in A[i..j] is ≥ key’
• Initialization: Since i = j − 1 (line 5), LI2(1) says that every element in A[j-1..j] is ≥ key. A[j-1] (i.e., A[i]) > key by explicit testing (line 6) and A[j] = key (line 4).
• Maintenance: The statement A[i+1] = A[i] (line 8) moves a value in A that is known to be greater than key (explicit testing at line 6)
into A[i+1]. Furthermore, A[i+1] previously held a value that is at
least equal to key (explicit testing in the previous iteration!).
• Termination: The loop terminates when i = 0 or A[i] ≤ key. At this point, we know that each element of A[i+1..j] is at least equal
to key because the last loop invariant LI2(i), i.e., A[i..j] ≥ key holds. Therefore, the postcondition is asserted.
2
Proof of LI2
LI2: ‘At the beginning of the ith iteration, every element in A[i..j] is ≥ key’
• Initialization: Since i = j − 1 (line 5), LI2(1) says that every element in A[j-1..j] is ≥ key. A[j-1] (i.e., A[i]) > key by explicit testing (line 6) and A[j] = key (line 4).
• Maintenance: The statement A[i+1] = A[i] (line 8) moves a value in A that is known to be greater than key (explicit testing at line 6)
into A[i+1]. Furthermore, A[i+1] previously held a value that is at
least equal to key (explicit testing in the previous iteration!).
• Termination: The loop terminates when i = 0 or A[i] ≤ key. At this point, we know that each element of A[i+1..j] is at least equal
to key because the last loop invariant LI2(i), i.e., A[i..j] ≥ key holds. Therefore, the postcondition is asserted.
2
Proof of LI2
LI2: ‘At the beginning of the ith iteration, every element in A[i..j] is ≥ key’
• Initialization: Since i = j − 1 (line 5), LI2(1) says that every element in A[j-1..j] is ≥ key. A[j-1] (i.e., A[i]) > key by explicit testing (line 6) and A[j] = key (line 4).
• Maintenance: The statement A[i+1] = A[i] (line 8) moves a value in A that is known to be greater than key (explicit testing at line 6)
into A[i+1]. Furthermore, A[i+1] previously held a value that is at
least equal to key (explicit testing in the previous iteration!).
• Termination: The loop terminates when i = 0 or A[i] ≤ key. At this point, we know that each element of A[i+1..j] is at least equal
to key because the last loop invariant LI2(i), i.e., A[i..j] ≥ key holds. Therefore, the postcondition is asserted.
2
Proof of LI1
LI1: ‘At the beginning of the jth iteration, A[1..j-1] is a sorted
permutation of the original A[1..j-1]’
• Initialization: LI1(1) holds because A[1..1] is trivially sorted
• Maintenance: For j > 2 assume that LI1(j-1) holds, i.e., A[1..j-2] is sorted. When the inner loop terminates, we know that:
• A[i] is ≤ key (by the termination condition of the inner loop). Since A[1..i] is sorted (by our assumption), every element of A[1..i] is ≤ key.
• A[i+1..j-2] is sorted (by our assumption) and each of its element ≥ key (by the post condition of the inner loop)
The statement A[i+1] = key (line 11) restores key and places it at
A[i+1]. Since every element in A[1..i] is ≤ key and each element in A[i+2, j-2] is ≥ key, A[1..j-1] is sorted and LI1(j) holds.
• Termination: The loop terminates when i = n + 1. By the loop invariant, A[1..n] is sorted and the precondition is asserted.
3
Proof of LI1
LI1: ‘At the beginning of the jth iteration, A[1..j-1] is a sorted
permutation of the original A[1..j-1]’
• Initialization: LI1(1) holds because A[1..1] is trivially sorted • Maintenance: For j > 2 assume that LI1(j-1) holds, i.e., A[1..j-2] is sorted. When the inner loop terminates, we know that:
• A[i] is ≤ key (by the termination condition of the inner loop). Since A[1..i] is sorted (by our assumption), every element of A[1..i] is ≤ key.
• A[i+1..j-2] is sorted (by our assumption) and each of its element ≥ key (by the post condition of the inner loop)
The statement A[i+1] = key (line 11) restores key and places it at
A[i+1]. Since every element in A[1..i] is ≤ key and each element in A[i+2, j-2] is ≥ key, A[1..j-1] is sorted and LI1(j) holds.
• Termination: The loop terminates when i = n + 1. By the loop invariant, A[1..n] is sorted and the precondition is asserted.
3
Proof of LI1
LI1: ‘At the beginning of the jth iteration, A[1..j-1] is a sorted
permutation of the original A[1..j-1]’
• Initialization: LI1(1) holds because A[1..1] is trivially sorted • Maintenance: For j > 2 assume that LI1(j-1) holds, i.e., A[1..j-2] is sorted. When the inner loop terminates, we know that:
• A[i] is ≤ key (by the termination condition of the inner loop). Since A[1..i] is sorted (by our assumption), every element of A[1..i] is ≤ key.
• A[i+1..j-2] is sorted (by our assumption) and each of its element ≥ key (by the post condition of the inner loop)
The statement A[i+1] = key (line 11) restores key and places it at
A[i+1]. Since every element in A[1..i] is ≤ key and each element in A[i+2, j-2] is ≥ key, A[1..j-1] is sorted and LI1(j) holds.
• Termination: The loop terminates when i = n + 1. By the loop invariant, A[1..n] is sorted and the precondition is asserted.
3