首页 > 排序算法7---快速排序算法

排序算法7---快速排序算法

原理:

通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序的目的。

#include 
#define MAXSIZE 9typedef struct {int r[MAXSIZE+1];    //r[0] 作为哨兵int length;            //待排序的数组长度
}SqList;void print(SqList L){int i;for(i=1; i){printf("%3d,",L.r[i]);}printf("%3d
",L.r[i]);
}void swap(SqList * L, int i, int j){int temp=L->r[i];L->r[i]=L->r[j];L->r[j]=temp;
}void QuickSort(SqList * L){void Qsort(SqList * L, int low, int high);Qsort(L,1,L->length);
}void Qsort(SqList * L, int low, int high){int Partition(SqList * L,int low, int high);int pivot;//注意在边界的地方要判断,pivot=1或者pivot=length,做处理if(low < high){pivot=Partition(L, low, high);//将L->[low-high]一分为二,返回pivotkey所在位置的下标Qsort(L,low,pivot-1);Qsort(L,pivot+1,high);}
}int Partition(SqList * L,int low, int high){int pivotkey=L->r[low];while(low < high){while(low < high && L->r[high]>=pivotkey) high--;swap(L,low,high);while(low < high && L->r[low]<=pivotkey) low++;swap(L,low,high);}return low;    //返回pivotkey当前的下标
    }int main(){SqList L;int num[MAXSIZE+1]={ 9,7,4,3,2,1,6,5,9,8};for(int i=0; i<10; i++){L.r[i] = num[i];}L.length=9;
//快排QuickSort(&L);print(L);
return 0;
}

时间复杂度

快速排序涉及到递归调用,所以该算法的时间复杂度还需要从递归算法的复杂度开始说起;
递归算法的时间复杂度公式:T[n] = aT[n/b] + f(n)  ;参考之前归并排序对递归算法时间复杂度的计算;


最优情况下时间复杂度

此时的时间复杂度公式则为:T[n] = 2T[n/2] + f(n);T[n/2]为平分后的子数组的时间复杂度,f[n] 为平分这个数组时所花的时间;
下面来推算下,在最优的情况下快速排序时间复杂度的计算(用迭代法):
                            T[n] =  2T[n/2] + n                                                                     ----------------第一次递归
                                                    =  2 { 2 T[n/4] + (n/2) }  + n                                               ----------------第二次递归

                                                    =  2^2 T[ n/ (2^2) ] + 2n

                                                    =  2^2  {  2 T[n/ (2^3) ]  + n/(2^2)}  +  2n                         ----------------第三次递归  

                                                    =  2^3 T[  n/ (2^3) ]  + 3n

                                                    =  2^m T[1]  + mn                                                  ----------------第m次递归(m次后结束),只需要对1个元素的情况进行复杂符分析,即T(1)。

               当最后平分的不能再平分时,也就是说把公式一直往下跌倒,到最后得到T[1]时,说明这个公式已经迭代完了(T[1]是常量了)。

               得到:T[n/ (2^m) ]  =  T[1]    ===>>   n = 2^m   ====>> m = logn;

               T[n] = 2^m T[1] + mn ;其中m = logn;

               T[n] = 2^(logn) T[1] + nlogn  =  n T[1] + nlogn  =  n + nlogn  ;其中n为元素个数

               又因为当n >=  2时:nlogn  >=  n  (也就是logn > 1),所以取后面的 nlogn,即最有情况下的时间复杂度为O(nlogn);(注意:这里logn表示以2为底的n的对数)

 

最差情况下时间复杂度                  这种情况时间复杂度就好计算了,就是冒泡排序的时间复杂度:T[n] = n * (n-1) = n^2 + n;

 

    平均时间复杂度    

       快速排序的平均时间复杂度也是:O(nlogn)。
平均的情况,设枢轴的关键字应该在第k的位置(1≤k≤n),那么:
用数学归纳法可证明,其数量级为0(nlogn).

空间复杂度

其实这个空间复杂度不太好计算,因为有的人使用的是非就地排序,那样就不好计算了(因为有的人用到了辅助数组,所以这就要计算到你的元素个数了);我就分析下就地快速排序的空间复杂度吧;
首先就地快速排序使用的空间是O(1)的,也就是个常数级;而真正消耗空间的就是递归调用了,因为每次递归就要保持一些数据;
 
稳定性:
由于关键字的比较和交换是跳跃进行的,因此,快速排序是不稳定的排序方法。

转载于:https://www.cnblogs.com/Allen-win/p/7307861.html

更多相关:

  •         Apache POI是一个开源的利用Java读写Excel,WORD等微软OLE2组件文档的项目。        我的需求是对Excel的数据进行导入或将数据以Excel的形式导出。先上简单的测试代码:package com.xing.studyTest.poi;import java.io.FileInputSt...

  • 要取得[a,b)的随机整数,使用(rand() % (b-a))+ a; 要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a; 要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1; 通用公式:a + rand() % n;其中的a是起始值,n是整数的范围。 要取得a到b之间的...

  • 利用本征图像分解(Intrinsic Image Decomposition)算法,将图像分解为shading(illumination) image 和 reflectance(albedo) image,计算图像的reflectance image。 Reflectance Image 是指在变化的光照条件下能够维持不变的图像部分...

  • 题目:面试题39. 数组中出现次数超过一半的数字 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入: [1, 2, 3, 2, 2, 2, 5, 4, 2] 输出: 2 限制: 1 <= 数组长度 <= 50000 解题: cl...

  • 题目:二叉搜索树的后序遍历序列 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。 参考以下这颗二叉搜索树:      5     /    2   6   /  1   3示例 1: 输入: [1,6,3,2,5] 输出...

  • 文章目录前言跳表结构时间复杂度空间复杂度高效的动态插入和删除跳表索引的动态更新总结详细实现...

  • 生成分析文件 命令行运行: valgrind --tool=callgrind ./palmGateMachine 检测完毕之后会生成一个文件callgrind.out.26805, 后面的数字其实是这个待测进程的pid 可视化方法 可视化方法 可视化工具 kcachegrind 1、下载地址: https://launchp...

  • MQTT 心跳和keepalive配置 内容: 正常MQTT 服务器端会配置一个超时时间,一般为60s, 在这个时间段内一个连接如果没有数据传输的话,服务端会主动断开连接以释放资源, 有两种方式可以规避这个问题: 方式1: 最为简单, 将keepalive的时间设置小于 服务端的超时时间,则客户端每隔 keepalive的时间就...

  • 概述 我们用jmeter做性能测试,必然需要学会分析测试报告。但是初学者常常因为对概念的不清晰,最后被测试报告带到沟里去。   常见的误区 分析响应时间全用平均值响应时间不和吞吐量挂钩响应时间和吞吐量不和成功率挂钩。。。。。   平均值特别不靠谱 平均值为什么不靠谱?相信大家读新闻的时候经常可以看到,平均工资,平均房价,平均支出,等等...

  • 原文: https://mp.weixin.qq.com/s/Dns-ucDwuDeR7lNSlibyAA 放假通知   今年7月1日放暑假 9月2日开学   今天,省教育厅发布通知,2019年全省中小学幼儿园暑期放假时间统一为7月1日,秋季开学时间9月2日。2020年寒假放假时间为1月18日,春季开学时间为2月10日。 刚刚...

  • 1. P117页,练习15:最高响应比 HRRF: 作业 提交时刻 运行时刻 开始时刻 完成时刻 周转时间/min 带权周转时间/min 1 10:00 2:00 10:00 12:00 120 120/120 2 10:10 1:00 12:25 13:25 195 195/60 3 1...