您的位置:首页 > 其它

八大排序——快速排序

2017-03-20 22:27 267 查看
作为一个学后台的同学,如果你不会希尔排序,我可以认为你学的不够,但如果你不会快速排序,那么我就要偷偷笑你了。快速排序算法最早由图灵奖的获得者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)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息