BUG: wrong search for pivot in quicker_sort

This PR corrects an error in the search for the existence of a distinct
pivot for sorting in the `quicker_sort` routines. This could lead to
`quicker_sort` wrongly believing that all items in a subarray are equal and
hence require no sorting.

While this doesn't explain #835 and #902, it may be related.
This commit is contained in:
jaimefrio
2014-03-11 00:48:10 -07:00
parent f4b260cb33
commit e6fc72011f
2 changed files with 37 additions and 37 deletions
+36 -36
View File
@@ -77,64 +77,64 @@ typedef enum {yes, no} yes_no;
yes_no find_pivot(EDGE *left, EDGE *right, double *pivot_ptr) yes_no find_pivot(EDGE *left, EDGE *right, double *pivot_ptr)
{ {
EDGE a, b, c, *p; EDGE a, b, c, *p;
a = *left; a = *left;
b = *(left + (right - left) /2 ); b = *(left + (right - left) / 2);
c = *right; c = *right;
o3(a,b,c); o3(a, b, c);
if (a.reliab < b.reliab) if (a.reliab < b.reliab)
{ {
*pivot_ptr = b.reliab; *pivot_ptr = b.reliab;
return yes; return yes;
} }
if (b.reliab < c.reliab) if (b.reliab < c.reliab)
{ {
*pivot_ptr = c.reliab; *pivot_ptr = c.reliab;
return yes; return yes;
} }
for (p = left + 1; p <= right; ++p) for (p = left + 1; p <= right; ++p)
{ {
if (p->reliab != left->reliab) if (p->reliab != left->reliab)
{ {
*pivot_ptr = (p->reliab < left->reliab) ? left->reliab : p->reliab; *pivot_ptr = (p->reliab < left->reliab) ? left->reliab : p->reliab;
return yes; return yes;
} }
return no;
} }
return no;
} }
EDGE *partition(EDGE *left, EDGE *right, double pivot) EDGE *partition(EDGE *left, EDGE *right, double pivot)
{ {
while (left <= right) while (left <= right)
{ {
while (left->reliab < pivot) while (left->reliab < pivot)
++left; ++left;
while (right->reliab >= pivot) while (right->reliab >= pivot)
--right; --right;
if (left < right) if (left < right)
{ {
swap (*left, *right); swap (*left, *right);
++left; ++left;
--right; --right;
} }
} }
return left; return left;
} }
void quicker_sort(EDGE *left, EDGE *right) void quicker_sort(EDGE *left, EDGE *right)
{ {
EDGE *p; EDGE *p;
double pivot; double pivot;
if (find_pivot(left, right, &pivot) == yes) if (find_pivot(left, right, &pivot) == yes)
{ {
p = partition(left, right, pivot); p = partition(left, right, pivot);
quicker_sort(left, p - 1); quicker_sort(left, p - 1);
quicker_sort(p, right); quicker_sort(p, right);
} }
} }
//--------------end quicker_sort algorithm ----------------------------------- //--------------end quicker_sort algorithm -----------------------------------
+1 -1
View File
@@ -104,8 +104,8 @@ yes_no find_pivot(EDGE *left, EDGE *right, double *pivot_ptr)
*pivot_ptr = (p->reliab < left->reliab) ? left->reliab : p->reliab; *pivot_ptr = (p->reliab < left->reliab) ? left->reliab : p->reliab;
return yes; return yes;
} }
return no;
} }
return no;
} }
EDGE *partition(EDGE *left, EDGE *right, double pivot) EDGE *partition(EDGE *left, EDGE *right, double pivot)