CSC212 Apr24

slide version

single file version

Contents

  1. Inserting integers in Order in an Array
  2. Insertion Sort: 1
  3. Insertion Sort: 2
  4. Insertion Sort: 3
  5. Insertion Sort: 4
  6. Insertion Sort: 5
  7. Insertion Sort: 6
  8. Insertion Sort: 7
  9. Writing Insertion in Java: 1
  10. Insertion in Java: 2
  11. Insertion in Java: 3
  12. Insertion in Java: 5
  13. Insertion in Java: 6
  14. Insertion in Java: 7
  15. Insertion Sort: 1
  16. Insertion Sort in Java: 2
  17. Insertion Sort in Java: 3
  18. Insertion Sort in Java: 4
  19. Bubble Sort: 1
  20. Bubble Sort: 2
  21. Bubble Sort: 3
  22. Bubble Sort: 4
  23. Bubble Sort: 5
  24. Bubble Sort: 6
  25. Bubble Sort: 6
  26. Min Selection Sort: 1
  27. Min Selection Sort: 2
  28. Min Selection Sort: 2
  29. Min Selection Sort: 3
  30. Min Selection Sort: 4
  31. Sorting String Arrays: 1
  32. Sorting Arrays of User Defined Class Type
  33. Example: Sorting an array of Strings
  34. Sample Run
  35. Program 2

Inserting integers in Order in an Array[1] [top]

This is conceptually easy.

Suppose that we have an array of size 10, and it currently only holds 4 integers.

Also assume that these are in sorted order. For example,

   Array: 17 26 45 65 
Position:  0  1  2  3  4  5  6  7  8  9

Now insert 33 (in order). The result is, of course

   Array: 17 26 33 45 65 
Position:  0  1  2  3  4  5  6  7  8  9

The 45 and 65 each were first moved one position to the right.

Then the 33 could be inserted at the free position

Insertion Sort: 1[2] [top]

An array of existing values can be sorted using the insertion idea.

Consider an array of size 10 that already has 5 integers values stored, but is not sorted in order:

   Array: 65 26 17 45 33 
Position:  0  1  2  3  4  5  6  7  8  9

We can think of this array as consisting of two parts:

Initially, the sorted part is just the single value at position 0 and the remaining values are unexamined.

   Array: 65 26 17 45 33 
Position:  0  1  2  3  4  5  6  7  8  9

Insertion Sort: 2[3] [top]

Now insert the first integer in the unexamined part in order into the first part.

   Array: 65 26 17 45 33 
Position:  0  1  2  3  4  5  6  7  8  9

The value 26 is smaller than 65, so 65 needs to be moved to the right.

But if we do this the wrong way we get

   Array: 65 65 17 45 33 
Position:  0  1  2  3  4  5  6  7  8  9

That is, the 26 that we are trying to insert is overwritten.

This can still work, but we need to have a temporary place to hold the value 26 until we can insert it.

Insertion Sort: 3[4] [top]

Using a temp integer variable to hold the next value being inserted into the first part, 26 can be inserted like this:

     tmp: -
   Array: 65 26 17 45 33 
Position:  0  1  2  3  4  5  6  7  8  9


     tmp: 26
   Array: 65  - 17 45 33 
Position:  0  1  2  3  4  5  6  7  8  9

     tmp: 26
   Array: -  65 17 45 33 
Position:  0  1  2  3  4  5  6  7  8  9

     tmp: -
   Array: 26 65 17 45 33 
Position:  0  1  2  3  4  5  6  7  8  9


Insertion Sort: 4[5] [top]

The next number to be inserted is the first one from the second unexamined part, 17:

     tmp: -
   Array: 26 65 17 45 33 
Position:  0  1  2  3  4  5  6  7  8  9

The steps to insert 17 into the first sorted part are:



     tmp: 17
   Array: 26 65  - 45 33 
Position:  0  1  2  3  4  5  6  7  8  9



     tmp: -
   Array: 17 26 65 45 33 
Position:  0  1  2  3  4  5  6  7  8  9

Insertion Sort: 5[6] [top]

How many insertions are required in Insertion Sort for an array with 5 integers?

The first integer doesn't have to be inserted into part 1; it's already there and part 2 consists of the remaining 5 - 1 integers.

So the answer is 5 - 1 = 4.

In general we will have to do n - 1 insertions to sort an array of n integers using the Insertion Sort algorithm.

Insertion Sort: 6[7] [top]

For the array

   Array: 22  8 35 10 19 23 16
Position:  0  1  2  3  4  5  6  7  8  9

What would the array look like after the first insertion?

What would it look like after the second insertion?

What would it look like after the third insertion?

Insertion Sort: 7[8] [top]

Answer:

Original array

   Array: 22  8 35 10 19 23 16
Position:  0  1  2  3  4  5  6  7  8  9

After one iteration of inserting:

   Array:  8 22 35 10 19 23 16
Position:  0  1  2  3  4  5  6  7  8  9

After two insertions

   Array:  8 22 35 10 19 23 16
Position:  0  1  2  3  4  5  6  7  8  9

After three insertions

   Array:  8 10 22 35 19 23 16
Position:  0  1  2  3  4  5  6  7  8  9

Writing Insertion in Java: 1[9] [top]

To translate the insertion and insertion sort into Java, let's first look at a single insertion in order.

That is, let's write a method, insert:

  public static void insert(int[] arr, int cnt, int x)

  Parameters
   arr:  an array of sorted integers
   cnt:  the number of integers stored in arr
     x:  a new integer to be inserted into arr in order

  Description 
    The insert method should use the insertion method to insert x at
    the proper place in the array arr so the at the result is still in
    sorted order.

    Precondition: The array arr should be large enought to hold one
    more integer. That is, arr.length should be > cnt.

Insertion in Java: 2[10] [top]

To insert another integer, x, into an array in order will usually require moving some of the values previously inserted.

An exception is the very first insertion.

Which items have to be moved? The ones greater than x.

How far does each of these have to be moved? Just to the next higher index.

The last element can be moved to the next higher index since that array position is not yet used.

Then we can move the next to last element, and so on, until we have moved all the elements bigger than x.

Insertion in Java: 3[11] [top]

Here are some examples of inserting one element into a sorted array.

In each case a variable k is initialized to be the index of the last element in the sorted array.

Then the array element is moved over and k is decremented until the correct place is found for the insertion of the new value.


Round 0 inserting 26
    Array:     -  -  -  -  -  -  -  - 
 Position: -1  0 
            k    

    Array:    26  -  -  -  -  -  -  - 
 Position: -1  0 
            k    
 26 inserted at position k + 1 = 0



Inserting 45
    Array:    26  -  -  -  -  -  -  - 
 Position: -1  0  1 
               k    

> 
    Array:    26 45  -  -  -  -  -  - 
 Position: -1  0  1 
               k    
 45 inserted at position k + 1 = 1

Insertion in Java: 5[12] [top]

A few more examples:


> 

Inserting 17
    Array:    26 45  -  -  -  -  -  - 
 Position: -1  0  1  2 
                  k    

> 
    Array:    26  - 45  -  -  -  -  - 
 Position: -1  0  1  2 
               k       

> 
    Array:     - 26 45  -  -  -  -  - 
 Position: -1  0  1  2 
            k          

> 
    Array:    17 26 45  -  -  -  -  - 
 Position: -1  0  1  2 
            k          
 17 inserted at position k + 1 = 0

Insertion in Java: 6[13] [top]

Last insertion example:



Inserting 33 
    Array:    17 26 45  -  -  -  -  -  - 
 Position: -1  0  1  2  3
                     k   


    Array:    17 26  - 45  -  -  -  -  -
 Position: -1  0  1  2  3
                  k   



    Array:    17 26 33 45  -  -  -  -  -
 Position: -1  0  1  2  3
                  k   

 33 inserted at position k + 1 = 2

Insertion in Java: 7[14] [top]

  public static void insert(int[] arr, int cnt, int x)

From the examples, we can note the following details for inserting x into arr:

    1	  public static void insert(int[] arr, int cnt, int x)
    2	  {
    3	    if ( cnt >= arr.length ) {
    4	      throw new IllegalArgumentException();
    5	    }
    6	
    7	    int k = cnt - 1;
    8	    while( k >= 0 && arr[k] > x ) {
    9	      arr[k+1] = arr[k];
   10	      k--;
   11	    }
   12	    arr[k+1] = x;
   13	  }

Lines 3 - 5: Handle the precondition; there should be enough room in
             the array for another element.

Line 7: Initialize k to be the position of the current last element

Line 8: Make sure k is not -1 before comparing x to arr[k]. If k is
-1, then this check will exit the loop and x will be inserted in
arr[k+1], that is, at arr[0]. If k is not -1, but x > arr[k], then
x should also be inserted in arr[k+1].

Line 9 - 10: If k is a valid index (k not -1) and x < arr[k], then
lines 9 - 10 move arr[k] to the "right" one position and decrement k.

Insertion Sort: 1[15] [top]

Using the insert method above we can easily implement the Insertion Sorting algorithm to sort an array.

    1	  public static void insertionSort(int[] arr, int cnt)
    2	  {
    3	    for(int i = 1; i < cnt; i++) {
    4	      insert(arr, i, arr[i]);
    5	    }
    6	  }

Line 3: The for loop starts with i = 1. This is because considering
just 1 element at position 0, that part of the array is "sorted". To
sort the array, we must insert the remaining cnt - 1
elements. The loop executes cnt - 1 times, each time
inserting one more element into its proper sorted position.

Line 4: At this call, the first i elements of arr are already
sorted. They are in positions 0 to i-1. So the next item from the
second part of the array to be inserted is arr[i].

Insertion Sort in Java: 2[16] [top]

    1	  public static void insertionSort(int[] arr, int cnt)
    2	  {
    3	    for(int i = 1; i < cnt; i++) {
    4	      insert(arr, i, arr[i]);
    5	    }
    6	  }

To sort an entire array it isn't necessary to have the separate insert method which only inserts one item.

The call to insert at line 4 can be replaced by the code for insert with some minor modifications.

Here is the insert code:

    1	  public static void insert(int[] arr, int cnt, int x)
    2	  {
    3	    if ( cnt >= arr.length ) {
    4	      throw new IllegalArgumentException();
    5	    }
    6	
    7	    int k = cnt - 1;
    8	    while( k >= 0 && arr[k] > x ) {
    9	      arr[k+1] = arr[k];
   10	      k--;
   11	    }
   12	    arr[k+1] = x;
   13	    
   14	  }

The call to insert in insertionSort passes i and i is < the number of elements in the array so the precondition check at lines 3 to 5 is not necessary.

The parameter x to insert is just arr[i].

Insertion Sort in Java: 3[17] [top]

So replacing parameter x by declaring it as a local variable x by setting it to arr[i] and removing the precondition check, we can replace the call to insert with the code from insert:

    1	  public static void insertionSort(int[] arr, int cnt)
    2	  {
    3	    for(int i = 1; i < cnt; i++) {
    4	      / * insert(arr, i, arr[i]); */
    5	      int x = arr[i];
    6	      int k = cnt - 1;
    7	      while( k >= 0 && arr[k] > x ) {
    8		arr[k+1] = arr[k];
    9		k--;
   10	      }
   11	      arr[k+1] = x;
   12	    }
   13	  }

Insertion Sort in Java: 4[18] [top]

We could also rewrite the inner while loop that does a single insertion using an equivalent for loop.

    1	  public static void insertionSort(int[] arr, int cnt)
    2	  {
    3	    for(int i = 1; i < cnt; i++) {
    4	      / * insert(arr, i, arr[i]); */
    5	      int x = arr[i];
    6	      for(int k = cnt - 1; k >= 0 && arr[k] > x; k--) {
    7		arr[k+1] = arr[k];
    8	      }
    9	      arr[k+1] = x;
   10	    }
   11	  }

Bubble Sort: 1[19] [top]

Bubble sort makes several passes over the elements of an array.

On each pass, bubble sort compares adjacent pairs of elements and swaps them if they are out of order from the first pair to the last pair.

On the first pass this results in the largest value being in the last array position.

So after the first pass, the largest value is in its correct sorted position and will be ignored from now on.

On each subsequent pass, bubble sort considers 1 fewer elements, ignoring the last one from the previous pass since it will also be in its correct sorted position.

After n-1 passes the array is sorted where n is the number of elements in the array.

Bubble Sort: 2[20] [top]

An essential, but simple ingredient in bubble sort and several other sorting algorithms is the code to swap two elements.

A third temporary variable is needed to swap the values of two integers.

(A red glass contains regular milk; a blue glass, skim milk. How would you swap the contents of the two glasses?)

This code does not swap x and y.

    int x = 5;
    int y = 10;

    x = y;   // Now x and y are both 10
    y = x;   // The are both still 10

A correct way of swapping x and y using a temporary:

int x = 5; int y = 10; int tmp = x; // save x's value in tmp x = y; // Now x and y are both 10, but tmp is still 5 y = tmp; // x is 10 and y is 5

    

Bubble Sort: 3[21] [top]

Here is code for one pass where k is the number of elements still being considered. The array elements at positions k, k+1, ... would already be in their correct sorted positions.

    1	  public static void pass(int[] a, int k)
    2	  {
    3	    for(int i = 0; i < k; i++) {
    4	      if ( a[i] > a[i+1] ) {
    5		int tmp = a[i];
    6		a[i] = a[i+1];
    7		a[i+1] = tmp;
    8	      }
    9	    }
   10	  }

Bubble Sort: 4[22] [top]

The code for one pass is not enough to sort an array; it only puts the largest value in the last position.

Here is bubble sort using the pass method:

    1	  public static void bubbleSort(int[] a, int cnt)
    2	  {
    3	    for(k = cnt; k > 1; k--) {
    4	      pass(a, k);
    5	    }
    6	  }

On the first call to pass, k is the number of elements stored in the array and pass will make one pass resulting in the largest value being put in possition the last position, a[k-1].

On each call to pass the number of elements decreases and the next largest value is put it its proper place.

If the number of elements considered in a pass is at least 2, there is something to do, but if the number of elements is just 1, then that element is already in its proper place.

So only cnt - 1 passes are needed (k = cnt, cnt - 1, ..., 2).

Bubble Sort: 5[23] [top]

Just as for insertion sort, we can replace the call to pass with the actual code.

Doing so results in the usual code for bubble sort:

    1	  public static void bubbleSort(int[] a, int cnt)
    2	  {
    3	    for(k = cnt; k > 1; k--) {
    4	      / * pass(a, k); */
    5	      for(int i = 0; i < k; i++) {
    6		if ( a[i] > a[i+1] ) {
    7		  int tmp = a[i];
    8		  a[i] = a[i+1];
    9		  a[i+1] = tmp;
   10		}
   11	      }
   12	    }
   13	  }

Bubble Sort: 6[24] [top]

For the array

   Array: 22  8 35 10 19 23 16
Position:  0  1  2  3  4  5  6  7  8  9

What would the array look like after the first pass?

What would it look like after the second pass?

What would it look like after the third pass?

Bubble Sort: 6[25] [top]

Answer:

Original array

   Array: 22  8 35 10 19 23 16
Position:  0  1  2  3  4  5  6  7  8  9

After one pass:

   Array:  8 22 10 19 23 16 35
Position:  0  1  2  3  4  5  6  7  8  9

After two passes

   Array:  8 10 19 22 16 23 35
Position:  0  1  2  3  4  5  6  7  8  9

After three passes

   Array:  8 10 19 16 22 23 35
Position:  0  1  2  3  4  5  6  7  8  9

Min Selection Sort: 1[26] [top]

Insertion sort is not the fastest sorting algorithm, but it generally performs a bit better than bubble sort and a lot better if the array is nearly sorted.

One problem with bubble sort is all the swapping.

Minimum Selection Sort works somewhat similarly to bubble sort, but avoids doing so many swaps.

A key idea is to keep track of the position of the minimum value found on one pass, but only swap when all the elements for that pass have been examined.

That is, the key idea is that if you know the position of the minimum value in an array, you can get the minimum value, but not conversely. So you have more information if you know the minimum value's position.

Min Selection Sort: 2[27] [top]

On the first pass, minimum selection sort finds the position of the minimum value stored in the array.

Then, and only then, does minimum selection sort swap the value at this position with the value at position 0.

Now position 0 can be ignored. The correct smallest value is in its proper place.

On each pass, the position of the minimum value out of values not already placed is found.

If the k smallest values have already been placed, they will be at positions 0, 1, ... k-1.

So the next smallest value should go at position k.

Min Selection Sort: 2[28] [top]

For the array

   Array: 22 23 35 19 10  8 16
Position:  0  1  2  3  4  5  6  7  8  9

What would the array look like after the first pass?

What would it look like after the second pass?

What would it look like after the third pass?

Min Selection Sort: 3[29] [top]

Answer:

The highlighted pair in each pass corresponds to the only swap in the pass.

Original array

   Array: 22 23 35 19 10  8 16
Position:  0  1  2  3  4  5  6  7  8  9

After one pass:

   Array:  8 23 35 19 10 22 16
Position:  0  1  2  3  4  5  6  7  8  9

After two passes

   Array:  8 10 35 19 23 22
Position:  0  1  2  3  4  5  6  7  8  9

After three passes

   Array:  8 10 19 35 23 22
Position:  0  1  2  3  4  5  6  7  8  9

Min Selection Sort: 4[30] [top]

Here is the code for minimum selection sort:

    1	  public static void minSelectionSort(int[] arr, int cnt)
    2	  {
    3	    for(int k = 0; k < cnt; k++) {
    4	      // Find minimum of a[k] ... a[cnt-1] and put it in a[k]
    5	      int minpos = k;
    6	      for(int i = k + 1; i < cnt; i++) {
    7		if ( a[minpos] > a[i] ) {
    8		  minpos = i;
    9		}
   10	      }
   11	      // Now swap once 
   12	      int tmp = a[minpos];
   13	      a[minpos] = a[k];
   14	      a[k] = tmp;
   15	  }

Sorting String Arrays: 1[31] [top]

Sorting arrays of Strings can use any of the sorting algorithms just discussed, except that comparisons must be done differently.

Instead of using the relational operators <, <=, etc. for integers, you must use the String method:

public int compareTo(String other)

    String x, y;

    x.compareTo(y) is < 0 if x comes before (is smaller than) y as Strings
    x.compareTo(y) is 0 if x and y are equal as Strings
    x.compareTo(y) is > 0 if x comes after (is bigger than) y as Strings

Also if swapping is required, the temporary variable should be of String type, not int.

Sorting Arrays of User Defined Class Type[32] [top]

If a class type has a compareTo method like that of String, then it determines an order on the instances of the class and the same code can be used to sort an array of that class type using that class's compareTo method.

Example: Sorting an array of Strings[33] [top]

This example uses maximum selection sort (instead of min selection sort).

Each pass of Max Selection Sort finds the position of the maximum value in the n items considered on that pass and then swaps the values at maxpos and n - 1, where the maximum belongs.

Then n is decremented and the process repeats until n is 1 and there is nothing left to do.

The String array used here is the array of strings passed on the command line.

    1	  
    2	  public static void sort(String[] a, int cnt)
    3	  {
    4	    for(int n = cnt; n > 1; n--) {
    5	      int maxpos = 0;
    6	      for(int i = 1; i < n; i++) {
    7		if ( a[i].compareTo(a[maxpos]) > 0 ) {
    8		  maxpos = i;
    9		}
   10	      }
   11	      String tmp = a[maxpos];
   12	      a[maxpos] = a[n-1];
   13	      a[n-1] = tmp;
   14	    }
   15	  }
   16	
   17	  public static void main(String[] args)
   18	  {
   19	    sort(args, args.length);
   20	    for(int i = 0; i < args.length; i++) {
   21	      System.out.println(args[i]);
   22	    }
   23	  }

Sample Run[34] [top]

>java sortStrings bob betty fred dino bam-bam 
bam-bam
betty
bob
dino
fred

Program 2[35] [top]

See the program 2 description on the hw page.