Sort Algorithm Fix

- The sort algorithm (Combsort11) was broken because it didn't
  consider all the possible variations of present/missing, same/
  different combinations of data, when performing a compare.  This
  led to an unstable sort, which is an infinite loop in Combsort11.
This commit is contained in:
Paul Beckingham 2009-03-02 23:49:13 -05:00
parent 1e70400143
commit a1b7516cf8

View file

@ -764,6 +764,32 @@ void Table::optimize (std::string& output)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Combsort11, with O(n log n) average, O(n log n) worst case performance. // Combsort11, with O(n log n) average, O(n log n) worst case performance.
//
// function combsort11(array input)
// gap := input.size
//
// loop until gap <= 1 and swaps = 0
// if gap > 1
// gap := gap / 1.3
// if gap = 10 or gap = 9
// gap := 11
// end if
// end if
//
// i := 0
// swaps := 0
//
// loop until i + gap >= input.size
// if input[i] > input[i+gap]
// swap(input[i], input[i+gap])
// swaps := 1
// end if
// i := i + 1
// end loop
//
// end loop
// end function
#define SWAP \ #define SWAP \
{ \ { \
int temp = order[r]; \ int temp = order[r]; \
@ -776,7 +802,7 @@ void Table::sort (std::vector <int>& order)
int gap = order.size (); int gap = order.size ();
int swaps = 1; int swaps = 1;
while (gap > 1 || swaps != 0) while (gap > 1 || swaps > 0)
{ {
if (gap > 1) if (gap > 1)
{ {
@ -797,10 +823,28 @@ void Table::sort (std::vector <int>& order)
Grid::Cell* left = mData.byRow (order[r], mSortColumns[c]); Grid::Cell* left = mData.byRow (order[r], mSortColumns[c]);
Grid::Cell* right = mData.byRow (order[r + gap], mSortColumns[c]); Grid::Cell* right = mData.byRow (order[r + gap], mSortColumns[c]);
if (left == NULL && right != NULL)
SWAP
if (left && right && *left != *right) // Data takes precedence over missing data.
if (left == NULL && right != NULL)
{
SWAP
break;
}
// No data - try comparing the next column.
else if (left == NULL && right == NULL)
{
keepScanning = true;
}
// Identical data - try comparing the next column.
else if (left && right && *left == *right)
{
keepScanning = true;
}
// Differing data - do a proper comparison.
else if (left && right && *left != *right)
{ {
switch (mSortOrder[mSortColumns[c]]) switch (mSortOrder[mSortColumns[c]])
{ {
@ -874,11 +918,7 @@ void Table::sort (std::vector <int>& order)
SWAP SWAP
break; break;
} }
break;
} }
else
keepScanning = true;
} }
++r; ++r;