In the last lecture we realized that there was a flaw with our strategy. In this lecture, we will try to change our strategy and along the way try to uncover the kinds of potential hazards we could run into. We will also understand how to do Regression Testing.


Regression Testing

Testing a piece of code to see that the changes we made to eliminate one bug did not re-introduce another previously eliminated bug is called regression testing. We will perform such tests for all the strategies that we discuss in this lecture.


Buggy Sort Routine

Strategy 1)

Could we move the pivot element to the middle of the array to be sorted? Here is the program after making the change:

void sort(int *array, int nelt)
{
    int mid, smallix, bigix ;
    if (nelt <= 1) return;
    mid = array[nelt/2];
    smallix = 0;
    bigix = nelt;
    while ( smallix < bigix )
        {
            while ( smallix < nelt && array[smallix] <= mid )
               smallix++;
            while ( bigix >=0 && array[bigix - 1] > mid )
                bigix--;
            t = array[smallix];
            array[smallix] = array[ bigix -1];
            array[bigix - 1] = t;
        }
 
    sort(array, smallix -1);
    sort(array + smallix, nelt - smallix);
}

Test Case

We design the test case so that potentially bad things happen:

nelt = 3
array[0] = 1
array[1] = 3
array[2] = 2

sort (int * array, 3)

Here is the execution trace:
Assuming we will take mid = array[floor(nelt/2)],

mid = 3

smallix = 0 -> 1 -> 2 -> 3 //At this point smallix becomes greater than nelt and we break out of the first inner while loop.

bigix = 3 // Since array[bigix -1] is not greater than mid we break out of the second inner while loop too.

Here comes th problem: We swap array[smallix] which is array[3] with array[bigix -1] which is array[2], the problem being that array[3] could be some garbage value.


Strategy 2)

How about varying smallix from 0 to (nelt -1)? Can you trace the execution for this case? Hint: See what happens if the last element in the array is an element that is smaller than the pivot element.


Strategy 3)

Modifying the code to take care of the problem in strategy 1, and changing the pivot element to array[0] again, the code looks something like this:

void sort(int *array, int nelt)
{
    int mid, smallix, bigix ;
    if (nelt <= 1) return;
    mid = array[0];
    smallix = 0;
    bigix = nelt;
    while ( smallix < bigix )
        {
            while ( smallix < nelt && array[smallix] <= mid )
               smallix++;
            while ( bigix >=0 && array[bigix - 1] > mid )
                bigix--;
            t = array[smallix];
            array[smallix] = array[ bigix -1];
            array[bigix - 1] = t;
        }

/* Look for modifications below */

if ( !(smallix == nelt || 0 == bigix) {                                                                                                                                                                                                                                t = array[smallix – 1];                                                                                                                                                                                                                                      array[smallix-1] = array[0];                                                                                                                                                                                                                                         array[0] = t;                                                                                                                                                                                                                                                      }

    sort(array, smallix -1);
    sort(array + smallix, nelt - smallix);
}

Test Case:

nelt = 3
array[0] = 3
array[1] = 2
array[2] = 1

mid = 3

smallix = 0 -> 1 -> 2 -> 3  // At this point smallix becomes greater than nelt and we break out of the first inner while loop.

bigix = 3 // Since array[bigix -1] is not greater than mid we break out of the second inner while loop too.

Now, since bigix != 0, we swap array[smallix -1] which is array[2] and array[0]. Hence the state of the array looks like this:

array[0] = 1
array[1] = 2
array[2] = 3

We make two recursive calls:

Call 1:                                                                                                         Call 2:

sort (array, 2)                                                                                              sort (array+3,0)

nelt = 2                                                                                                        nelt = 0

mid = 1                                                                                                       return;   

smallix = 0-> 1 //At this point we stop  because array[1] > mid

bigix = 2 -> 1 // At this point we stop because array[0] !> array[0]                                                                                                                                                                   

Hence we swap array[0] with array[0].

Call sort (array, 0) since smallix = 1. This call returns at the recursion bounding test.

Call sort (array+1,1) since nelt - smallix = 1. This call too returns at the recursion bounding condition..

Hence, we have in the array:

array[0] = 1
array[1] = 2
array[2] = 3

Thus, our sort code seems to work in this case.


But, are our tests conclusive? How do you prove that your algorithm is correct? More to come in the next class.