Working with Ordered Data

Steven Zeil

Last modified: Dec 26, 2016
Contents:

1 Sorting

1.1 Insertion Sort

Basic idea:

1.1.1 Getting Started

template <class T>
void insertionSort (T* array, int size) 
{ 
   for (int firstOutOfOrder = 1;➁ 
        firstOutOfOrder < size; )➂
    {
     addInOrder (array, firstOutOfOrder, ➀
                 array[firstOutOfOrder]);
    }
}

:Basically, this algorithm does repeated calls to addInOrder, adding a different element each time

: We start the loop at 1, not 0, because, by definition a list of one element (array[0..0]) is already ordered

:We don’t put firstOutOfOrder++ in the increment position of the loop, because addInOrder already increments its second parameter, and we don’t want it incremented twice each time around the loop.

1.1.2 All for One

So these two functions, together, should sort the array.

template <class T>
void insertionSort (T* array, int size)
{
  for (int firstOutOfOrder = 1; 
       firstOutOfOrder < size; )
    {
     addInOrder (array, firstOutOfOrder, 
                 array[firstOutOfOrder]);
    }
}

template <class T>
int addInOrder (T* array, int& size, T value)
{
  // Make room for the insertion
  int toBeMoved = size - 1;
  while (toBeMoved >= 0 && value < array[toBeMoved]) {
    array[toBeMoved+1] = array[toBeMoved];
    --toBeMoved;
  }
  // Insert the new value
  array[toBeMoved+1] = value;
  ++size;
  return toBeMoved+1;
}

1.1.3 and One for All

Now let’s merge them …

template <class T>
void insertionSort (T* array, int size)
{
  for (int firstOutOfOrder = 1; firstOutOfOrder < size; 
       ++firstOutOfOrder)
    {
     T value = array[firstOutOfOrder];
     int toBeMoved = firstOutOfOrder - 1;
     while (toBeMoved >= 0 && value < array[toBeMoved]) {
       array[toBeMoved+1] = array[toBeMoved];
       --toBeMoved;
     }
     // Insert the new value
     array[toBeMoved+1] = value;
   }
}

You can play with the both the insertion sort algorithm and the other sorting algorithms mentioned in the text here.

2 Binary Search

2.1 Binary Search Code

binSearch.cpp
int binarySearch(const int list[], int listLength, 
    int searchItem)
{
    int first = 0;
    int last = listLength - 1;
    int mid; ➀

    bool found = false;

    while (first <= last && !found) ➁
    {
      mid = (first + last) / 2; ➂

      if (list[mid] == searchItem) ➃
            found = true;
        else 
	  if (list[mid] > searchItem) ➄
                last = mid - 1;
            else
                first = mid + 1;
    }

    if (found) 
        return mid;
    else
        return -1;
}

The easiest way to understand this algorithm is probably to just try it.

2.2 What’s So Special About Binary Search?

How many array elements will we examine while doing binary search?

Array Size Comparisons
1 1
2 2
4 3
8 4
16 5
32 6
64 7
128 8

Compare to sequential and ordered search which visit, on average, half of the array locations per search.

2.4 Speed of Binary Search (cont.)

Array Size Comparisons
256 9
512 10
1024 11
2048 12
4096 13
8192 14
16384 15
32768 16

For an array with over 32000 elements, a sequential search would look, on average, at more than 16000 elements before finding the one we wanted.

Binary search does the same after examining just 16.

That’s a 1000x speedup!