八大排序——快速排序

作为一个学后台的同学,如果你不会希尔排序,我可以认为你学的不够,但如果你不会快速排序,那么我就要偷偷笑你了。快速排序算法最早由图灵奖的获得者Tony Hoare设计出来,更牛逼的是,这个算法被列为了20世纪十大算法之一。对,没错,是十大算法,不是十大排序算法,这足以看出这个排序算法在学界中大牛心目中的地位,我们这些程序猿还有什么理由不去学习它?不说玩笑话,下面让我们真正的体会一下快速排序。

快速排序算法

快速排序(Quick Sort),其基本思想为:在序列中选出一个元素作为“枢纽”,经过一趟排序将序列分割成两部分,其中一部分均比“枢纽”元素小,另一部分均比“枢纽”元素大,然后把这两部分作为新的序列执行同样的操作,直到元素数无法进行分割为止。细心的同学会发现,整个操作其实是一个递归调用,排序会将“枢纽”元素放置到合适的位置(合适的位置意味着它的位置不需再改变),而其它元素都会放置到合适的区域(注意的说的是合适的区域),而分割的作用就是使被放到合适位置的元素越来越多,合适的区域越来越精确,直到合适的区域精确到成为一个位置为止(仔细体会)。小二,上代码:

#include <stdio.h>

void sort(int a[], int left, int right)
{
    if(left >= right)//如果left大于或者等于right就代表已经整理完成一个部分了
    {
        return;
    }
    int i = left;
    int j = right;
    int key = a[left];//取下标为left的元素为“枢纽”元素,并将其赋值给key

    while(i < j)//当i和j"相遇"的时候,说明所有元素都被比较了一遍,这时候就不用再循环
    {
        while(i < j && key <= a[j])
        {
            j--;//向前寻找
        }

        a[i] = a[j];//数值覆盖
        while(i < j && key >= a[i])
        {
            i++;//向后寻找
        }
        a[j] = a[i];//数值覆盖
    }

    a[i] = key;//将“枢纽”元素放在合适的位置
    sort(a, left, i - 1);//用同样的方式对分出来的左边的小组进行同上的做法
    sort(a, i + 1, right);//用同样的方式对分出来的右边的小组进行同上的做法
}
void main()
{
    int a[]={5,6,1,4,9,2,9};
    int i;
    int length=sizeof(a)/sizeof(int);
    sort(a,0,length-1);
    for(i=0;i<length;i++){
        printf("%d\t",a[i]);
    }
    printf("\n");
}

光看代码很难理解其中的变换过程,下表是第一次排序的数值变化,大家可以体会一下:
这里写图片描述
其中标黄色的部分为被变化的值,从图中也解答了大家对20和25行代码注释的一个疑问(即数值覆盖会不会造成数据丢失),大家可以看到,第一次覆盖,其实是“枢纽”元素被覆盖,而我们已经提前将“枢纽”元素赋给了key,而其后的数值覆盖覆盖的都是冗余的值,因为我们每覆盖一次都没有将之前位置的值清空,那么它就是冗余的,覆盖它不会造成数据丢失。
注:快速排序的时间复杂度为O(nlogn)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值