快速排序基本思想:
通过一趟排序,将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,再分别对这两部分记录进行下一趟排序,已达到整个序列有序。
案例:
一趟快速排序的过程
代码:
进行一趟快速排序的算法:
//一趟快速排序
int quickOnePass(Sqlist *L, int low, int high)
{
int i = low, j = high;
L->R[0] = L->R[i];//R[0]作为临时单元和哨兵
do {
while ((L->R[0].key < L->R[j].key) && j > i) {
j--;
}
if (j > i) {
L->R[i] = L->R[j];
i++;
}
while ((L->R[i].key < L-R[0].key) && j > i) {
i++;
}
if (j > i) {
L->R[j] = L->R[i];
j--;
}
} while(i != j);//i=j时退出扫描
L->R[i] = L->R[0];
return i;
}
快速排序递归算法:
在进行一趟快速排序之后,再使用同样的方法对两个子序列进行排序,直到子序列的记录个数为1为止。
//快速排序递归算法
void quickSort(Sqlist *L, int low, int high) {
int k;
if (low < high) {
k = quickOnePass(L, low, high);//一趟快速排序
//序列分为两部分,分别对每个子序列进行递归排序
quickSort(L, low, k-1);
quickSort(L, k+1, high);
}
}
快速排序非递归算法:
//快速排序非递归算法
#define MAX_STACK 100
void quickSort(Sqlist *L, int low, int high) {
int k, stack[MAX_STACK], top = 0;
do {
while (low < high) {
k = quickOnePass(L, low, high);
stack[++top] = high;//第二个子序列的上界入栈
stack[++top] = k + 1;//第二个子序列的下界入栈
high = k - 1;
}
if (top != 0) {
low = stack[top--];
high = stack[top--];
}
} while(top != 0 && low < high);
}
分析:
快速排序的平均时间复杂度为:T(n) = O(nlog2^n)
从所需要的附加空间来看,快速排序算法是递归调用,系统内用堆栈保存递归参数,当每次划分比较均匀时,栈的最大深度为[log2^n]+1
快速排序的空间复杂度为S(n) = O(log2^n).
快速排序是不稳定的。
另外一篇使用顺序表存储的快速排序,更简单易懂https://blog.csdn.net/fu_jian_ping/article/details/89146606