算法描述:由东尼·霍尔所发展的一种排序算法;选定主元后,将待排序列划分为两个子集,分别进行快速排序,也是分治法的一种典型应用。快速排序的动态图示如下所示:
复杂度分析:最坏时间复杂度为 O(N2) ,平均时间复杂度也为 O(NlogN) ,效率较高。最坏状况不常见,事实上,快速排序通常明显比其他 O(NlogN) 算法更快,因为其内部循环可以在大部分的架构上很有效率地被实现出来。
主要特点:
- 不稳定(如果有元素等于主元,需要停下来交换);
- 占用额外内存 O(logN) ;
- 递归对小规模数据排序时,可能还不如插入排序快,可在程序中定义一个阈值。
- 通常明显比其他 O(NlogN) 算法更快。
C语言描述:
#include<stdio.h>
#include<stdlib.h>
typedef int ElementType;
void Swap(ElementType *A, ElementType *B) {
ElementType temp = *A;
*A = *B;
*B = temp;
}
void Insertion_Sort(ElementType Data[], int N) {
int P, i;
ElementType temp;
for (P = 1; P < N; P++) {
temp = Data[P];
for (i = P; i > 0 && Data[i - 1] > temp; i--)
Data[i] = Data[i - 1];
Data[i] = temp;
}
}
/* 选主元 */
ElementType Median3(ElementType Data[], int Left, int Right) {
int Center = (Left + Right) / 2;
if (Data[Left] > Data[Center])
Swap(&Data[Left], &Data[Center]);
if (Data[Left] > Data[Right])
Swap(&Data[Left], &Data[Right]);
if (Data[Center] > Data[Right])
Swap(&Data[Center], &Data[Right]);
/*A[Left] <= A[Center] <= A[Right]*/
Swap(&Data[Center], &Data[Right - 1]); /*将基准Pivot藏到右边*/
int i;
for (i = Left; i <= Right; i++) {
printf("%d ", Data[i]);
}
printf("\n");
return Data[Right - 1]; /*返回基准Pivot*/
}
/* 核心递归函数 */
void Qsort(ElementType Data[], int Left, int Right) {
int Pivot, Cutoff = 2;
int Low, High;
if (Cutoff < Right - Left + 1) { /*如果序列元素充分多,进入快排*/
Pivot = Median3(Data, Left, Right);
/* 划分子集:将序列中比基准小的移到基准左边,大的移到右边 */
Low = Left;
High = Right - 1;
while (1) {
while (Data[++Low] < Pivot);
while (Data[--High] > Pivot);
if (Low < High) Swap(&Data[Low], &Data[High]);
else break;
}
Swap(&Data[Low], &Data[Right - 1]); /*将基准换到正确的位置*/
Qsort(Data, Left, Low - 1); /*递归解决左边*/
Qsort(Data, Low + 1, Right); /*递归解决右边*/
}
else Insertion_Sort(Data + Left, Right - Left + 1); /*元素太少,用简单排序*/
}
/* 快速排序C语言描述 */
void Quick_Sort(ElementType Data[], int N) {
Qsort(Data, 0, N - 1);
}
int main() {
ElementType Data[] = {28, 3, 33, 23, 15, 30, 19, 10, 20, 22 };
Quick_Sort(Data, 10);
return 0;
}