Sorting an Array

  1. Another one of the most widely encountered programming task is sorting a list of data according to certain criteria.

  2. A list of numbers may need to be sorted from the smallest number to the largest number, or vice versa.

  3. A list of names may need to be sorted alphabetically.

  4. Many different algorithms have been discovered, the simplest one is called selection sort. We will discuss the selection sort algorithm and write a function to implement it below.

  5. Suppose we are given an array of integers a[ ], partially filled with number_used integers. The function sort must rearrange the elements so that

    a[0] <= a[1] <= a[2] <= . . . <= a[number_used - 1]

    after the function is called.

  6. One way to do that is to inspect the elements of the array from the beginning to the end to find the smallest element. This element is extracted from the array a and is placed as the first element in a new array, say b. Scan array a again, but this time containing one element less, to find the smallest element. This element is extracted from array a and placed as the second element in array b. Repeat this (number_used - 1) times, then array a will have exactly one element left. Simply put this element as the (number_used - 1)-th element in b.

  7. There are two problems with this approach:

    • Once the smallest element is found from array a, how do we extract it from array a so that this element is not inspected again?
    • If the extracted elements are put into another array, b, then b has to have the same size as array a. This requires extra amount of memory.

  8. Both problems can be solved in the following implementation of the selection sort algorithm.

  9. Inspect the elements of the array from the beginning to the end to find the smallest element. Swap the position of this element with the first element (unless the first element happens to be the smallest). Inspect the elements of the array starting with the second element to the end to find the next smallest element. Swap the position of the element found with the second element. Repeat this procedure a total of (number_used - 1) times.

  10. The following illustrates step by step how the algorithm works:

    step     a[0]     a[1]     a[2]     a[3]     a[4]     a[5]
    ------------------------------------------------------------------
      0           5          3          7         0          9         2
      1           0          3          7         5          9         2
      2           0          2          7         5          9         3
      3           0          2          3         5          9         7
      4           0          2          3         5          9         7
      5           0          2          3         5          7         9

  11. //Implementation of the above selection sort algorithm and
    //illustration of how it can be used to sort an integer array

    #include <iostream>
    using namespace std;

    void fill_array(int a[ ], int size, int& number_used);
    //Precondition: size is the declared size of the array a.
    //Postcondition: number_used is the number of values stored in a.
    //a[0] through a[number_used - 1] have been filled with
    //nonnegative integers read from the keyboard.

    void sort(int a[ ], int number_used);
    //Precondition: number_used <= declared size of the array a.
    //The array elements a[0] through a[number_used - 1] have values.
    //Postcondition: The values of a[0] through a[number_used - 1] have
    //been rearranged so that a[0] <= a[1] <= ... <= a[number_used - 1].

    void swap_values(int& v1, int& v2);
    //Interchanges the values of v1 and v2.

    int index_of_smallest(const int a[ ], int start_index, int number_used);
    //Precondition: 0 <= start_index < number_used.
    //Referenced array elements have values.
    //Returns the index i such that a[i] is the smallest of the values
    //a[start_index], a[star_index + 1], ..., a[number_used - 1].

    int main( )
    {
        cout << "Program to sort numbers in ascending order.\n";

        int sample_array[10], number_used;
        fill_array(sample_array, 10, number_used);
        sort(sample_array, number_used);

        cout << "In sorted order the numbers are:\n";
        for (int index = 0; index < number_used; index++)
            cout << sample_array[index] << " ";
        cout << endl;

        return 0;
    }

    //Uses iostream:
    void fill_array(int a[ ], int size, int& number_used)
    {
        cout << "Enter up to " << size << " nonnegative whole numbers.\n"
                    << "Mark the end of the list with a negative number.\n";

        int next, index = 0;
        cin >> next;
        while ((next >= 0) && (index < size))
        {
            a[index] = next;
            index++;
            cin >> next;
        }

        number_used = index;
    }

    void sort(int a[ ], int number_used)
    {
        int index_of_next_smallest;
        for (int index = 0; index < number_used - 1; index++)
        {
            //Place the correct value in a[index]:
            index_of_next_smallest = index_of_smallest(a, index, number_used);
            swap_values(a[index], a[index_of_next_smallest]);
            //a[0] <= a[1] <=...<= a[index] are the smallest of the original array
            //elements. The rest of the elements are in the remaining positions.
        }
    }

    void swap_values(int& v1, int& v2)
    {
        int temp;
        temp = v1;
        v1 = v2;
        v2 = temp;
    }


    int index_of_smallest(const int a[ ], int start_index, int number_used)
    {
        int min = a[start_index],
        index_of_min = start_index;
        for (int index = start_index + 1; index < number_used; index++)
            if (a[index] < min)
            {
                min = a[index];
                index_of_min = index;
                //min is the smallest of a[start_index] through a[index]
            }

        return index_of_min;
    }

    Since this function returns only the index for the smallest element and not its value, the body of the above index_of_smallest function can be replaced by the following:

    {
        int index_of_min = start_index;
        for (int index = start_index + 1; index < number_used; index++)
            if (a[index] < a[index_of_min])
            {
                index_of_min = index;
            }

        return index_of_min;
    }