快速排序

  快速排序是由東尼·霍爾所發展的一種排序算法。在平均狀況下,排序 n 個項目要Ο(n log n)次比較。在最壞狀況下則需要Ο(n2)次比較,但這種狀況並不常見。事實上,快速排序通常明顯比其他Ο(n log n) 演算法更快,因為它的內部循环(inner loop)可以在大部分的架構上很有效率地被實作出來。

  快速排序使用分治法(Divide and conquer)策略來把一個序列(list)分為兩個子序列(sub-lists)。

  步驟為:

  1. 從數列中挑出一個元素,稱為 "基準"(pivot),
  2. 重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面(相同的數可以到任一邊)。在這個分割結束之後,該基準就處於數列的中間位置。這個稱為分割(partition)操作。
  3. 递归地(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\t", a[i]);
    }
    printf("\n");
}

/* 数据交换 */
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 代码实现部分有所改动

posted @ 2013-09-04 16:48  DKMP  阅读(168)  评论(0编辑  收藏  举报