一个改进的快速排序实现
一、改进地方:
1) 递归改为用栈实现
2) 当划分数量小时(小于10个)停止划分,使用插入排序
二、实现代码
#define SK_EMPTY() (pos == 0)
#define SK_CLEAR() {pos = 0;}
#define SK_PUSH(l, r) {stack[pos++] = l; stack[pos++] = r;}
#define SK_POP(l, r) {r = stack[--pos]; l = stack[--pos];}
void QSort(int *data, int n)
{
int l, r, i, j, pos = 0;
int stack[1000]; //Here, set the fixed stack size just for simplify.
int t;
l = 0; r = n -1;
SK_CLEAR();
SK_PUSH(l, r);
while (!SK_EMPTY())
{
SK_POP(l, r);
//If the amount of point is too little
if (r - l <= 10)
{
//Insertion Sort
for (i = l + 1; i <= r; i++)
{
j = i; t = data[i];
while (j > 0 && t < data[j - 1])
{
data[j] = data[j - 1];
j--;
}
data[j] = t;
}
continue;
}
//Partition
t = data[r];
i = l; j = r;
do
{
while (i < j && data[i] <= t) ++i;
if (i < j) {data[j--] = data[i];}
while (i < j && data[j] >= t) --j;
if (i < j) {data[i++] = data[j];}
} while (i < j);
data[i] = t;
SK_PUSH(l, i - 1);
SK_PUSH(i + 1, r);
}
}
#define SK_CLEAR() {pos = 0;}
#define SK_PUSH(l, r) {stack[pos++] = l; stack[pos++] = r;}
#define SK_POP(l, r) {r = stack[--pos]; l = stack[--pos];}
void QSort(int *data, int n)
{
int l, r, i, j, pos = 0;
int stack[1000]; //Here, set the fixed stack size just for simplify.
int t;
l = 0; r = n -1;
SK_CLEAR();
SK_PUSH(l, r);
while (!SK_EMPTY())
{
SK_POP(l, r);
//If the amount of point is too little
if (r - l <= 10)
{
//Insertion Sort
for (i = l + 1; i <= r; i++)
{
j = i; t = data[i];
while (j > 0 && t < data[j - 1])
{
data[j] = data[j - 1];
j--;
}
data[j] = t;
}
continue;
}
//Partition
t = data[r];
i = l; j = r;
do
{
while (i < j && data[i] <= t) ++i;
if (i < j) {data[j--] = data[i];}
while (i < j && data[j] >= t) --j;
if (i < j) {data[i++] = data[j];}
} while (i < j);
data[i] = t;
SK_PUSH(l, i - 1);
SK_PUSH(i + 1, r);
}
}
三、补充
当然,此算法还可进一步改进,比如改为3路划分,或者或三平分分区法而不是以最右边的值作为划分中轴。