关于quick_sort中的partition问题
dot99 2003-10-30 09:11:11 按照
http://algorithm.myrice.com/algorithm/commonalg/sort/internal_sorting/quick_sort/quick_sort.htm
所介绍的qsort算法
我写了下面的快速排序算法
typedef int DT;
#define smallenough 12
void qsort(DT*, int, int);
int partition(DT*, int, int);
void insert_sort(DT*, int, int);
DT select_pviot(DT*, int, int);
void swap(DT&, DT&);
void qsort(DT* dtArr, int p, int r)
{
int q;
if (r-p <= smallenough)
insert_sort(dtArr, p, r);
else {
q = partition(dtArr, p, r);
qsort(dtArr, p, q);
qsort(dtArr, q+1, r);
}
}
int partition(DT* dtArr, int p, int r)
{
DT pviot = select_pviot(dtArr, p, r);
int i, j;
i = p-1;
j = r+1;
while (1) {
do {
j--;
} while(dtArr[j] <= pviot); //cause err?
do {
i++;
} while(dtArr[i] >= pviot);
if (i<j)
swap(dtArr[j], dtArr[i]);
else if (j != r)
return j;
else
return j-1;
}
}
其把待分组数据分成了>=和<=两部分
然后递归求解
当数据“比较随机”的时候,算法可以顺利运行
但是,当我构造一个数组时,问题出来了
比如以下数据
0, 3, 2, 2, 3 [设第一个数的下标为m]
当pviot = 3时候
do {
j--;
} while(dtArr[j] <= pviot); //cause err?
将j移动到m-1
do {
i++;
} while(dtArr[i] >= pviot);
将i移动到m
然后return j;
再下一次递归调用时候
q = partition(dtArr, p, r);
qsort(dtArr, p, q); (A)
qsort(dtArr, q+1, r); (B)
由于q < p 所以(A)直接return
(B)就出现错误了 q+1 = p
还是call上次递归调用时候的p, r值
然后就一直递归下去了,直到stack overflow
如果将 cause err 的条件改为
while(dtArr[j] < pviot);
即分为< 和 >= 两部分
则不会出现问题
当然,这是在smallenough足够小(等于3)的情况下测试出来的,当smallenough够大的时候
嵌入的insert_sort()已经将一组数据处理好,不太可能回出现上面的情况。
大家讨论一下我错在什么地方