next up previous contents
Next: Selection Sort: Introduction Up: Sorting Previous: Sorting   Contents

Insertion Sort: Introduction [128]




Algorithm:

Make n-1 passes.

At pass i=2..n, elements 1..i-1 are already sorted.

Store the element at i in a temporary variable.

Moving downwards from i, move larger elements up.

Stop if a smaller (or equal) element found.

Stop if done moving downwards.

Insert the temporary variable in the hole that is left.



Insertion Sort: Example [129]




Original 34 8 64 51 32 21 Moves
After i=2     64 51 32 21 3
After i=3 8 34 64 51 32 21 2
After i=4 8 34     32 21 3
After i=5 8         21 5
After i=6 8           6




What if the input data was already sorted in ascending order?

What if the input data was already sorted in descending order?

What happens with duplicates?

Do they keep the same relative order? (Stability)



Insertion Sort: insert [130]

% gcc -o insert insert.c                               > tcc insert.c

Data File with Test Case: insert.dat: 6 34 8 64 51 32 21

% insert insert.dat
 6   19   14 [  8 21 32 34 51 64 ]  0  0

% insert insert.dat step
 n move comp    1  2  3  4  5  6    i  j
 6    0    0 [ 34  8 64 51 32 21 ]  0  0
 6    2    1 [ 34 34 64 51 32 21 ]  2  2
 6    3    2 [  8 34 64 51 32 21 ]  2  1
 6    5    3 [  8 34 64 51 32 21 ]  3  3
 6    7    4 [  8 34 64 64 32 21 ]  4  4
 6    8    5 [  8 34 51 64 32 21 ]  4  3
 6   10    6 [  8 34 51 64 64 21 ]  5  5
 6   11    7 [  8 34 51 51 64 21 ]  5  4
 6   12    8 [  8 34 34 51 64 21 ]  5  3
 6   13    9 [  8 32 34 51 64 21 ]  5  2
 6   15   10 [  8 32 34 51 64 64 ]  6  6
 6   16   11 [  8 32 34 51 51 64 ]  6  5
 6   17   12 [  8 32 34 34 51 64 ]  6  4
 6   18   13 [  8 32 32 34 51 64 ]  6  3
 6   19   14 [  8 21 32 34 51 64 ]  6  2



Insertion Sort: insert.c [131]

void insertion(input_type a[], int n) {  
  int i,j; 
  input_type tmp; 
  
  a[0] = MIN_DATA;                                                 
  for (i=2; i<=n; i++) {                           COUNT                         
    tmp = a[i];                            move    n-1
    j = i;                                                             
    while (tmp < a[j-1]) {                 comp    i
      a[j] = a[j-1];                       move    i-1
      j--;                                                         
    }
    a[j] = tmp;                            move    n-1
  } 
}

Why do we need the sentinel?

How does it affect performance?

Note that a swap works but increases the moves.



Insertion Sort: Analysis [132]

Data Compares= ${\displaystyle \sum_{i=2}^{n} \sum_{j=1}^{i} 1=\sum_{i=2}^{n} i =\sum_{i=1}^{n}i - 1 = \frac{n(n+1)}{2} - 1}$

Data Moves = ${\displaystyle \sum_{i=2}^{n}(2 + \sum_{j=1}^{i-1}1)=\sum_{i=2}^{n}2+i-1=\sum_{i=2}^{n}(i+1)}$

= ${\displaystyle \sum_{i=1}^{n}i - 1 + \sum_{i=2}^{n} 1 = \frac{n(n+1)}{2} -1 + (n-1) = \frac{n(n+1)}{2} + n -2}$



Data Compares: O( )

Data Moves: O( )

CORRECTNESS:

  for (i=2; i<=n; i++)  /* Invariant: 1..i-1 are sorted */

1. On entry to loop: i=2 and 1..i-1 are sorted.

2. On each interation: ith entry is sorted and i++.

The loop invariant is maintained.

3. On exit from loop: What is the value of i?


next up previous contents
Next: Selection Sort: Introduction Up: Sorting Previous: Sorting   Contents
Ted Billard 2001-10-25