八大排序——快速排序
2017-03-20 22:27
267 查看
作为一个学后台的同学,如果你不会希尔排序,我可以认为你学的不够,但如果你不会快速排序,那么我就要偷偷笑你了。快速排序算法最早由图灵奖的获得者Tony Hoare设计出来,更牛逼的是,这个算法被列为了20世纪十大算法之一。对,没错,是十大算法,不是十大排序算法,这足以看出这个排序算法在学界中大牛心目中的地位,我们这些程序猿还有什么理由不去学习它?不说玩笑话,下面让我们真正的体会一下快速排序。
光看代码很难理解其中的变换过程,下表是第一次排序的数值变化,大家可以体会一下:
其中标黄色的部分为被变化的值,从图中也解答了大家对20和25行代码注释的一个疑问(即数值覆盖会不会造成数据丢失),大家可以看到,第一次覆盖,其实是“枢纽”元素被覆盖,而我们已经提前将“枢纽”元素赋给了key,而其后的数值覆盖覆盖的都是冗余的值,因为我们每覆盖一次都没有将之前位置的值清空,那么它就是冗余的,覆盖它不会造成数据丢失。
注:快速排序的时间复杂度为O(nlogn)。
快速排序算法
快速排序(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)。
相关文章推荐
- 八大排序-快速排序
- 八大排序--交换排序 之 快速排序
- Java 八大排序之——快速排序
- 八大排序之快速排序
- Java提高 - 八大排序方法之快速排序
- 八大排序--快速排序
- 八大排序之快速排序
- 八大排序——快速排序
- 数据结构与算法系列之一:八大排序之快速排序
- 内部交换排序---快速排序
- (原创)选择排序与快速排序及D&C算法的延伸
- javascript实现八大排序
- 快速排序和合并排序的比较(时间和比较步数)
- 交换排序_快速排序
- Java排序法(冒泡排序、选择排序、快速排序)
- 八大排序--快速排序
- 通过自己编写的stack类实现快速排序的非递归排序
- 开贴聊八大排序算法之直接插入排序(一)
- 直接插入排序、快速排序和堆排序的C实现
- 算法导论学习笔记(一)排序算法之快速排序