快速排序是由東尼·霍爾所發展的一種排序算法。在平均狀況下,排序 n 個項目要Ο(n log n)次比較。在最壞狀況下則需要Ο(n2)次比較,但這種狀況並不常見。事實上,快速排序通常明顯比其他Ο(n log n) 演算法更快,因為它的內部循环(inner loop)可以在大部分的架構上很有效率地被實作出來。
快速排序使用分治法(Divide and conquer)策略來把一個序列(list)分為兩個子序列(sub-lists)。
步驟為:
- 從數列中挑出一個元素,稱為 "基準"(pivot),
- 重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面(相同的數可以到任一邊)。在這個分割結束之後,該基準就處於數列的中間位置。這個稱為分割(partition)操作。
- 递归地(recursive)把小於基准值元素的子數列和大於基准值元素的子數列排序。
遞迴的最底部情形,是數列的大小是零或一,也就是永遠都已經被排序好了。雖然一直遞迴下去,但是這個演算法總會結束,因為在每次的迭代(iteration)中,它至少會把一個元素擺到它最後的位置去。
#include <stdio.h> int a[100] = { 5, 2, 1, 1, 2, 3, 4, 6, 3, 66, 77, 33, 22, 11 }; /* 输出数组前n各元素 */ void prt(int n) { int i; for (i = 0; i < n; i++) { printf("%d ", a[i]); } printf(" "); } /* 数据交换 */ void swap(int *a, int *b) { int tmp; tmp = *a; *a = *b; *b = tmp; } void quick_sort(int a[], int left, int right) { int i = left + 1, j = right; int key = a[left]; if (left >= right) return; //从i++和j--两个方向搜索不满足条件的值并交换,直至i等于j //条件为:i++方向小于key,j--方向大于key while (1) { while (a[j] >= key&&j>i) j--; while (a[i] <= key&&i<j) i++; if(i == j) break; swap(&a[i],&a[j]); } //关键数据放到‘中间’ //此处由上面逻辑保证了a[i]==a[j]。 //由于先执行j--,所以新排列中除非所有元素都大于a[left],否则a[j]一定小于等于a[left] //而元素都大于a[left]时不需要交换,a[j]等于a[left]时无需交换 if(a[left]>a[j]) swap(&a[left],&a[j]); if(left < i - 1) quick_sort(a, left, i - 1); if(j < right) quick_sort(a, j , right); } int main(void) { /* 排序与输出 */ quick_sort(a, 0, 13); prt(14); return 0; }
摘自http://zh.wikipedia.org/wiki/%E5%BF%AB%E9%80%9F%E6%8E%92%E5%BA%8F 代码实现部分有所改动