Sorting
CSE 225 Data Structures and Algorithms
               Sorting
       Outline
   We are going to look at three simple sorting techniques:
    Bubble Sort, Selection Sort and Insertion Sort.
   We will write code for Bubble Sort, Selection Sort and
    Insertion Sort. We will analyze the running time for
    each of the above.
                                                               2
     Bubble Sort
   Compare each element (except the last one) with its
    neighbor to the right
       If they are out of order, swap them
       This puts the largest element at the very end
       The last element is now in the correct and final place
   Compare each element (except the last two) with its
    neighbor to the right
       If they are out of order, swap them
       This puts the second largest element next to last
       The last two elements are now in their correct and final places
   Compare each element (except the last three) with its
    neighbor to the right
       Continue as above until you have no unsorted elements on the left
                                                                            3
  Example of Bubble Sort
7 2 8 5 4   2 7 5 4 8   2 5 4 7 8   2 4 5 7 8
2 7 8 5 4   2 7 5 4 8   2 5 4 7 8   2 4 5 7 8
2 7 8 5 4   2 5 7 4 8   2 4 5 7 8     (done)
2 7 5 8 4   2 5 4 7 8
2 7 5 4 8
                                                4
     Code for Bubble Sort
   void bubbleSort(int a[], int size) {
      int outer, inner;
      for (outer = size - 1; outer > 0; outer--) { // counting down
        for (inner = 0; inner < outer; inner++) {        // bubbling up
           if (a[inner] > a[inner + 1]) { // if out of order...
              int temp = a[inner];        // ...then swap
              a[inner] = a[inner + 1];
              a[inner + 1] = temp;
           }
        }
      }
    }
                                                                          5
     Analysis of Bubble Sort
   for (outer = size - 1; outer > 0; outer--) {
      for (inner = 0; inner < outer; inner++) {
         if (a[inner] > a[inner + 1]) {
            // code for swap omitted
    } } }
   Let n = size of the array
   The outer loop is executed n-1 times (call it n, that’s close enough)
   Each time the outer loop is executed, the inner loop is executed
      Inner loop executes n-1 times at first, linearly dropping to just once
      On average, inner loop executes about n/2 times for each execution
        of the outer loop
      In the inner loop, the comparison is always done (constant time), the
        swap might be done (also constant time)
   Result is n * n/2, that is, O(n2/2) = O(n2)
                                                                                6
        Another sort: Selection Sort
   Given an array of length n,
       Search elements 0 through n-1 and select the smallest
            Swap it with the element in location 0
       Search elements 1 through n-1 and select the smallest
            Swap it with the element in location 1
       Search elements 2 through n-1 and select the smallest
            Swap it with the element in location 2
       Search elements 3 through n-1 and select the smallest
            Swap it with the element in location 3
       Continue in this fashion until there’s nothing left to search
                                                                        7
  Example and analysis of Selection Sort
7 2 8 5 4
               The Selection Sort might swap an
                array element with itself--this is
2 7 8 5 4
                harmless, and not worth checking for
               Analysis:
2 4 8 5 7          The outer loop executes n-1 times
                   The inner loop executes about n/2
2 4 5 8 7           times on average (from n to 2 times)
                   Work done in the inner loop is constant
2 4 5 7 8           (swap two array elements)
                   Time required is roughly (n-1)*(n/2)
                   You should recognize this as O(n2)
                                                              8
        Code for Selection Sort
void selectionSort(int a[], int size) {
      int outer, inner, min;
      for (outer = 0; outer < size - 1; outer++) { // outer counts down
         min = outer;
         for (inner = outer + 1; inner < size; inner++) {
            if (a[inner] < a[min]) {
                min = inner;
            }
         }
         // a[min] is least among a[outer]..a[size - 1]
         int temp = a[outer];
         a[outer] = a[min];
         a[min] = temp;
      }
   }
                                                                          9
  One step of insertion sort
               sorted          next to be inserted
3 4 7 12 14 14 20 21 33 38 10 55 9 23 28 16
                                                 temp
less than 10                                      10
3 4 7 10 12 14 20
      12 14    14 21 21 38
                  20 33 33 10
                           38 55 9 23 28 16
                 sorted
                                                        10
       Code for Insertion Sort
void insertionSort(int a[], int size) {
   int inner, outer;
    for (outer = 1; outer < size; outer++) {
       int temp = a[outer];
       inner = outer;
       while (inner > 0 && a[inner - 1] >= temp) {
          a[inner] = a[inner - 1];
          inner--;
       }
       a[inner] = temp;
    }
}
                                                     11
         Insertion Sort – Analysis
   Running time depends on not only the size of the array
    but also the contents of the array.
   Best-case:               O(n)
       Array is already sorted in ascending order.
       Inner loop will not be executed.
   Worst-case:                O(n2)
       Array is in reverse order:
       Inner loop is executed i-1 times, for i = 2,3, …, n
   Average-case:              O(n2)
       We have to look at all possible initial data organizations.
   So, Insertion Sort is O(n2)
        Summary
   Bubble Sort, Selection Sort, and Insertion Sort are all O(n2)
   As we will see later, we can do much better than this with
    somewhat more complicated sorting algorithms
   Within O(n2),
       Bubble Sort is very slow, and should probably never be used for anything
       Selection Sort is intermediate in speed
       Insertion Sort is usually the fastest of the three--in fact, for small arrays
        (say, 10 or 15 elements), insertion sort is faster than more complicated
        sorting algorithms
   Selection Sort and Insertion Sort are “good enough” for small
    arrays
                                                                                        13
     Divide and Conquer
   Recursive in structure
       Divide the problem into sub-problems that are similar
        to the original but smaller in size
       Conquer the sub-problems by solving them recursively.
         If they are small enough, just solve them in a
        straightforward manner.
       Combine the solutions to create a solution to the
        original problem
    An Example: Merge Sort
Sorting Problem: Sort a sequence of n elements into
  non-decreasing order.
   Divide: Divide the n-element sequence to be
    sorted into two subsequences of n/2 elements each
   Conquer: Sort the two subsequences recursively
    using merge sort.
   Combine: Merge the two sorted subsequences to
    produce the sorted answer.
           Merge Sort – Example
           Original Sequence                        Sorted Sequence
     18 26 32       6   43 15     9   1    1    6    9    15   18 26 32 43
 18 26 32       6       43 15     9   1   6    18 26 32        1    9    15   43
                                                                              43
18 26      32   6       43 15     9   1   18 26       6   32   15 43      1   9
18    26   32   6       43   15   9   1   18   26    32   6    43   15   9    1
18    26   32   6       43   15   9   1
     Merge-Sort (A, p, r)
INPUT: a sequence of n numbers stored in array A
OUTPUT: an ordered sequence of n numbers
MergeSort (A, p, r) // sort A[p..r] by divide & conquer
1     if p < r
2   then q  (p+r)/2
3       MergeSort (A, p, q)
4       MergeSort (A, q+1, r)
5       Merge (A, p, q, r) // merges A[p..q] with A[q+1..r]
  Initial Call: MergeSort(A, 1, n)
               Procedure Merge
Merge(A, p, q, r)
1 Copy two sorted sub arrays of A into L and R
2 i1
3 j1                                               Input: Array containing
4 for k p to r                                  sorted subarrays A[p..q] and
5       do if L[i]  R[j]                                  A[q+1..r].
6           then A[k]  L[i]
                                                   Output: Merged sorted
7                  ii+1
                                                    subarray in A[p..r].
8           else A[k]  R[j]
9                  jj+1
        Merging two sorted arrays
20 12
13 11
7   9
2   1
            Merging two sorted arrays
20 12
13 11
7       9
2       1
    1
            Merging two sorted arrays
20 12         20 12
13 11         13 11
7       9      7   9
2       1      2
    1
            Merging two sorted arrays
20 12         20 12
13 11         13 11
7       9      7       9
2       1      2
    1              2
            Merging two sorted arrays
20 12         20 12        20 12
13 11         13 11        13 11
7       9      7       9   7   9
2       1      2
    1              2
            Merging two sorted arrays
20 12         20 12        20 12
13 11         13 11        13 11
7       9      7       9   7       9
2       1      2
    1              2           7
            Merging two sorted arrays
20 12         20 12        20 12       20 12
13 11         13 11        13 11       13 11
7       9      7       9   7       9      9
2       1      2
    1              2           7
            Merging two sorted arrays
20 12         20 12        20 12       20 12
13 11         13 11        13 11       13 11
7       9      7       9   7       9        9
2       1      2
    1              2           7        9
            Merging two sorted arrays
20 12         20 12        20 12       20 12    20 12
13 11         13 11        13 11       13 11    13 11
7       9      7       9   7       9        9
2       1      2
    1              2           7        9
            Merging two sorted arrays
20 12         20 12        20 12       20 12    20 12
13 11         13 11        13 11       13 11    13 11
7       9      7       9   7       9        9
2       1      2
    1              2           7        9        11
            Merging two sorted arrays
20 12         20 12        20 12       20 12    20 12   20 12
13 11         13 11        13 11       13 11    13 11   13
7       9      7       9   7       9        9
2       1      2
    1              2           7        9        11
            Merging two sorted arrays
20 12         20 12        20 12       20 12    20 12   20 12
13 11         13 11        13 11       13 11    13 11   13
7       9      7       9   7       9        9
2       1      2
    1              2           7        9        11      12
            Merging two sorted arrays
20 12         20 12        20 12       20 12        20 12    20 12
13 11         13 11        13 11       13 11        13 11    13
7       9      7       9   7       9          9
2       1      2
    1              2           7          9            11     12
                Time = (n) to merge a total of n elements
                               (linear time).