快速排序小结

快速排序小结

大纲:

1.快排的原理

2.最坏情况

3.优化快排的方法

4.一般写法与更好的写法

1.快排的原理(本文重点)

         伪代码:

Void sqsort(int left,int right){

1.随便找个数aN

2.把要排序的数组分成以下 区间

<aN|<aN|<aN|…|==aN|==aN|==aN|…|>aN|>aN|>aN|…|

3.分别递归<aN与>aN的两个部分

If(left<最右边的<aN.sub) sqsort(left,最右边的<aN.sub);

If(最左边的>aN.sub >最左边的) sqsort(最左边的>aN.sub,right);

}

2.最坏情况

1.数组为有序或相同

2.任何能让快排每次递归的区间都只比上一次递归区间少一元素的数据

最坏情况后果:

  快排会退化成冒泡

  具体请见算法导论或其它博客

3.优化快排的方法

1.使用随机数找aN

2.随机三个取中值为aN

3.最左,中间,最右取中值为aN

4.数据效小时用插入排序

5.尾递归

6. …

4.一般写法与更好的写法

一般,详细请看:http://developer.51cto.com/art/201403/430986.htm

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 int a[10000005];
 4 void swap(int *a, int *b) {
 5     int t = *a;
 6     *a = *b;
 7     *b = t;
 8 }
 9 int sj(int l, int r) {
10     return rand() % (r - l + 1) + l;
11 }
12 void qSort(int l,int r) {
13     int i = l,j = r;
14     swap(&a[l],&a[sj(l,r)]);//始终以最左为基准
15     while (i < j) {
16         while (i < j&&a[j] >= a[l])j--;while (i < j&&a[i] <= a[l])i++;//前面后面分别找个不该在此区间的
17         //只有j在前才能归位最左基准,要是j在后那就以i-1归位
18         if (i < j) { swap(&a[i], &a[j]); }//把两站错区间的交换到正确区间
19     }
20     swap(&a[l],&a[i]);//归位基准
21     if(l<i-1)qSort(l, i - 1);//<aN区间递归
22     if(i+1<r)qSort(i+1,r);//>aN区间递归
23 }
24 int main() {
25     int n;
26     freopen("in.in", "r", stdin);
27     scanf("%d", &n);
28     for (int i = 1;i <= n;i++)scanf("%d", &a[i]);
29     qSort(1, n);
30     for (int i = 1;i <= n;i++)printf("%d ", a[i]);
31     return 0;
32 }

更好:2017/3/4 网上没详解这个的,这种的性能简直出奇好

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 int a[10000005];
 4
 5 void swap(int *a, int *b) {
 6     int t = *a;
 7     *a = *b;
 8     *b = t;
 9 }
10
11 void quicksort(int left,int right)
12 {
13     int i,j,base;i=left; j=right;base=a[(left+right)/2];
14     //基准数随意选了位于中间的
15     while (i<=j){
16        while (a[j]>base) j--;while (a[i]<base) i++;//前面后面分别找个不该在此区间的
17         //j在前还是i在前随意
18        //while (a[i]<base) i++;while (a[j]>base) j--;
19        if (i <= j) {
20             swap(&a[i],&a[j]);//交换
21             i++;j--;//是个小优化
22         }
23     }
24     //到此,区间划分完成 。这种写法更注重区间的划分,而不是在意基准数的归位
25     if (left<j) quicksort(left,j);//<aN区间递归
26     if (i<right) quicksort(i,right);//>aN区间递归
27 }
28 int main(){
29     int n;
30     freopen("in.in","r",stdin);
31     scanf_s("%d",&n);
32     for (int i=0;i<n;i++)scanf_s("%d",&a[i]);
33     quicksort(0,n-1);
34     for (int i=0;i<n;i++)printf("%d ",a[i]);
35     return 0;
36 }

总的来说就是 1.减少了递归层次2.与遍历次数3.解决了繁锁的基准数操作问题

10485765个重复数测试,这种1分25秒完成,传统3分种的时候爆栈

普通版评测:https://www.luogu.org/record/show?rid=1818379

更优版评测:https://www.luogu.org/record/show?rid=1821228

#include <stdio.h>#include <stdlib.h>int a[10000005];void swap(int *a, int *b) {int t = *a;*a = *b;*b = t;}int sj(int l, int r) {return rand() % (r - l + 1) + l;}void qSort(int l,int r) {int i = l,j = r;swap(&a[l],&a[sj(l,r)]);//始终以最左为基准while (i < j) {while (i < j&&a[j] >= a[l])j--;while (i < j&&a[i] <= a[l])i++;//前面后面分别找个不该在此区间的//只有j在前才能归位最左基准,要是j在后那就以i-1归位if (i < j) { swap(&a[i], &a[j]); }//把两站错区间的交换到正确区间}swap(&a[l],&a[i]);//归位基准if(l<i-1)qSort(l, i - 1);//<aN区间递归if(i+1<r)qSort(i+1,r);//>aN区间递归}int main() {int n;freopen("in.in", "r", stdin);scanf("%d", &n);for (int i = 1;i <= n;i++)scanf("%d", &a[i]);qSort(1, n);for (int i = 1;i <= n;i++)printf("%d ", a[i]);return 0;}

时间: 2024-08-05 19:09:01

快速排序小结的相关文章

数据结构与算法之三 深入学习排序

在本章中,你将学习: 通过使用快速排序来排序数据 通过使用归并排序来排序数据 快速排序算法: 快速排序是最有效率的排序算法之一,此算法基于分治法 连续将问题细分为更小的问题,直到问题成为可以直接解决的小问题 在快速排序算法中,你: 从名为枢轴的列表处选择元素. 将列表划分为两部分: 列表左端的所有元素小于等于枢轴. 列表右端的所有元素大于枢轴. 在此列表两部分的正确位置存储枢轴. 划分之后为创建的两个子列表重复此过程(找枢轴的过程). 直到每个子列表中只剩一个元素. 思想:就是不断找出符合条件的

快速排序算法小结

         快速排序是对冒泡排序的一种改进.它的基本思想是:通过一躺排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一不部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列.          假设要排序的数组是a[6],长度为7,首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一躺快速排序.一躺快速排序的算法是: 1).设

排序算法小结

排序算法经过了很长时间的演变,产生了很多种不同的方法.对于初学者来说,对它们进行整理便于理解记忆显得很重要.每种算法都有它特定的使用场合,很难通用.因此,我们很有必要对所有常见的排序算法进行归纳. 我不喜欢死记硬背,我更偏向于弄清来龙去脉,理解性地记忆.比如下面这张图,我们将围绕这张图来思考几个问题. 上面的这张图来自一个PPT.它概括了数据结构中的所有常见的排序算法.现在有以下几个问题: 1.每个算法的思想是什么?     2.每个算法的稳定性怎样?时间复杂度是多少?     3.在什么情况下

常见排序算法小结

排序算法经过了很长时间的演变,产生了很多种不同的方法.对于初学者来说,对它们进行整理便于理解记忆显得很重要.每种算法都有它特定的使用场合,很难通用.因此,我们很有必要对所有常见的排序算法进行归纳. 我不喜欢死记硬背,我更偏向于弄清来龙去脉,理解性地记忆.比如下面这张图,我们将围绕这张图来思考几个问题. 上面的这张图来自一个PPT.它概括了数据结构中的所有常见的排序算法.现在有以下几个问题: 1.每个算法的思想是什么?      2.每个算法的稳定性怎样?时间复杂度是多少?      3.在什么情

算法导论6:排序小结和最值取法 2016.1.6

今天想做测试各个排序算法运行时间比较的程序,来对这几天学的排序算法小结一下.所以我先生成了1000000个1~150之间的随机数存到文件里.然后做了一个测试运行时间的程序.想看一下结构.但是结果效果并不太好.实践中,自己做的qsort函数和mergesort函数并没有理想中的那么快. 结果是这样:(可能并不准确,但却是是运行结果) 库函数快速排序:0.139000 seconds自制快速排序:0.375000 seconds归并排序:0.358000 seconds堆排序:0.525000 se

【转】排序算法小结

排序算法经过了很长时间的演变,产生了很多种不同的方法.对于初学者来说,对它们进行整理便于理解记忆显得很重要.每种算法都有它特定的使用场合,很难通用.因此,我们很有必要对所有常见的排序算法进行归纳. 我不喜欢死记硬背,我更偏向于弄清来龙去脉,理解性地记忆.比如下面这张图,我们将围绕这张图来思考几个问题. 上面的这张图来自一个PPT.它概括了数据结构中的所有常见的排序算法.现在有以下几个问题: 1.每个算法的思想是什么?      2.每个算法的稳定性怎样?时间复杂度是多少?      3.在什么情

常用排序算法小结

1 #include <stdio.h> 2 #include <stdlib.h> 3 4 5 //the basic bubble sort 6 void maopao1(int *num,int len) 7 { 8 int i,j; 9 int temp; 10 for (i = 0; i < len-1; ++i) 11 { 12 for (j = i+1; j<len; ++j) 13 { 14 if (num[i]>num[j]) 15 { 16 t

交换排序:快速排序

快速排序(Quick Sort)也是一种交换排序,它在排序中采取了分治策略. 快速排序的主要思想: 从待排序列中选取一元素作为轴值(也叫主元). 将序列中的剩余元素以该轴值为基准,分为左右两部分.左部分元素不大于轴值,右部分元素不小于轴值.轴值最终位于两部分的分割处. 对左右两部分重复进行这样的分割,直至无可分割. 从快速排序的算法思想可以看出,这是一递归的过程. 两个问题: 要想彻底弄懂快速排序,得解决两个问题: 如何选择轴值?(轴值不同,对排序有影响吗?) 如何分割? 问题一:轴值的选取?

算法导论-排序(二)快速排序、随机化快速排序

目录 1.本文介绍 2.快速排序 3.随机化快速排序 4.完整源码 5.参考资料 内容 1.本文介绍 主要内容分为两部分,一部分是介绍快速排序算法,分析其在最好.最坏以及最好最差交替出现情况下的算法效率:另一部分则是介绍随机化快排算法,以及分析其算法复杂度.最后给出c++实现代码. 2.快速排序 快速排序也是基于分治思想,首先把要排序的数组分为两份,然后再分别对分好的子数组进行快速排序.当子数组为1个元素时递归介绍,排序完成.快速排序属于“原地排序”,就是说在原有的数组内存上排序.不占用其他内存