快速排序

实践中最快的已知排序算法。
平均效率=O(NlogN)的递归算法。

算法的思想是,先找出数列中的一个枢纽,然后在每次递归中,把小于枢纽的元素放枢纽左边,大于枢纽的元素放数组右边,即先做到“大概有序”,再切分数组,逐步递归达到全局有序。

注意和归并排序的区别:
快速排序先调整,后递归。
归并排序先递归,后调整。

小数组(N<20)的情况下,快速排序不如插入排序好。所以,当递归多次后数组变得很小时,就应该使用插入排序作为辅助了。

代码:
#include <stdio.h>
 
void InserSort(int *array, unsigned int n)
{
    int i, j;
    int temp;
     
    /* 排列n个数要进行n-1趟比较 */
    for (i = 1; i < n; i++)
    {
        temp = array[i];
         
        for (j = i-1; j >= 0 && array[j] > temp; j--)
            array[j+1] = array[j];
 
        array[j+1] = temp;
    }
}
 
void exchange(int *a, int *b)
{
    int tmp;
    tmp = *a;
    *a = *b;
    *b = tmp;
}
 
int Median(int *array, int left, int right)
{
    int mid = (left+right)/2;
     
    if (array[left] > array[right])
        exchange(&array[left], &array[right]);
     
    if (array[left] > array[mid])
        exchange(&array[left], &array[mid]);
         
    if (array[right] < array[mid])
        exchange(&array[right], &array[mid]);
     
    exchange(&array[mid], &array[right-1]);
     
    return array[right-1];
}
 
void Sort(int *array, int left, int right)
{
    int pivot;
    int i, j;
     
    if (left+3 <= right)
    {
        /* Median 的作用:
         * 1.把左端元素、右端元素、枢纽元素进行排序
         * 2.把枢纽和倒数第二个元素对调
         * 3.返回枢纽值
         */
        pivot = Median(array, left, right);
         
        /* 注意,这里可以直接跳过通过 Median 函数排过序的三个元素 */
        i = left + 1;
        j = right - 2;
         
        while (1)
        {
            while(array[i] < pivot)
                i++;
            while(array[j] > pivot)
                j--;
             
            if (i < j)
                exchange(&array[i], &array[j]);
            else
                break;
        }
        /* 把枢纽还原 */
        exchange(&array[i], &array[right-1]);
         
        Sort(array, left, i-1);
        Sort(array, i+1, right);
    }
    else
        /* 这里用插入排序效率更高 */
        InserSort(array+left, right-left+1);
}
 
void QuickSort(int *array, int N)
{
    Sort(array, 0, N-1);
}
 
int main(void)
{
    int array[] = {150,80,40,30,10,70,110,100,20,90,60,50,120,140,130};
    int len = sizeof(array)/sizeof(array[0]);
    int i;
     
    QuickSort(array, len);
 
    for (i = 0; i < len; i++)
        printf("%d ", array[i]);
    printf("\n");
     
    return 0;
}

运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值