在企业的面试或是考研的面试中, 快速排序可以说是出现频率最高的一个问题, 本文就快排做一个总结以帮助大家理解
快速排序介绍
快速排序 (Quick Sort) 使用分治法策略它的基本思想是: 选择一个基准数, 通过一趟排序将要排序的数据分割成独立的两部分; 其中一部分的所有数据都比另外一部分的所有数据都要小然后, 再按此方法对这两部分数据分别进行快速排序, 整个排序过程可以递归进行, 以此达到整个数据变成有序序列
小编推荐一个学 C 语言 / C++ 的学习裙 六九九, 四七零, 五九六 , 无论你是大牛还是小白, 是想转行还是想入行都可以来了解一起进步一起学习! 裙内有开发工具, 很多干货和技术资料分享!
这些是 C/C++ 能做的
服务器开发工程师人工智能云计算工程师信息安全 (黑客反黑客) 大数据 数据平台嵌入式工程师流媒体服务器数据控解图像处理音频视频开发工程师游戏服务器分布式系统游戏辅助等
快速排序流程如下:
从数列中挑出一个基准值
将所有比基准值小的摆放在基准前面, 所有比基准值大的摆在基准的后面(相同的数可以到任一边); 在这个分区退出之后, 该基准就处于数列的中间位置
递归地把 "基准值前面的子数列" 和 "基准值后面的子数列" 进行排序
快速排序图文说明
下面以数列 a={30,40,60,10,20,50}为例, 演示它的快速排序过程(如下图)
小编推荐一个学 C 语言 / C++ 的学习裙 六九九, 四七零, 五九六 , 无论你是大牛还是小白, 是想转行还是想入行都可以来了解一起进步一起学习! 裙内有开发工具, 很多干货和技术资料分享!
上图只是给出了第 1 趟快速排序的流程在第 1 趟中流程如下, 首先设置基数 x=a[i]=a[0], 即 x=30
从 "右 --> 左" 查找小于 x 的数: 找到满足条件的 数 a[j]=20, 此 时 j=4; 然后将 a[j]赋值 a[i], 此时 i=0; 接着从左往右遍历;
从 "左 --> 右" 查找大于 x 的数: 找到满足条件的数 a[i]=40, 此时 i=1; 然后将 a[i]赋值 a[j], 此时 j=4; 接着从右往左遍历;
从 "右 --> 左" 查找小于 x 的数: 找到满足条件的数 a[j]=10, 此时 j=3; 然后将 a[j]赋值 a[i], 此时 i=1; 接着从左往右遍历
从 "左 --> 右" 查找大于 x 的数: 找到满足条件的数 a[i]=60, 此时 i=2; 然后将 a[i]赋值 a[j], 此时 j=3; 接着从右往左遍历
从 "右 --> 左" 查找小于 x 的数: 没有找到满足条件的数当 i>=j 时, 停止查找; 然后将 x 赋值给 a[i]第一趟遍历结束!
根据上面的思路, 不难写出下面的快速排序实现:
/* * 快速排序 * * 参数说明: * a -- 待排序的数组 * l -- 数组的左边界(例如, 从起始位置开始排序, 则 l=0) * r -- 数组的右边界(例如, 排序截至到数组末尾, 则 r=a.length-1) */void quick_sort(int a[], int l, int r){ if (l <r) { int i,j,x; i = l; j = r; x = a[i]; while (i < j) { while(i < j && a[j]> x) j--; // 从右向左找第一个小于 x 的数 if(i < j) a[i++] = a[j]; while(i < j && a[i] < x) i++; // 从左向右找第一个大于 x 的数 if(i < j) a[j--] = a[i]; } a[i] = x; quick_sort(a, l, i-1); /* 递归调用 */ quick_sort(a, i+1, r); /* 递归调用 */ }}
小编推荐一个学 C 语言 / C++ 的学习裙 六九九, 四七零, 五九六 , 无论你是大牛还是小白, 是想转行还是想入行都可以来了解一起进步一起学习! 裙内有开发工具, 很多干货和技术资料分享!
快速排序的时间复杂度和稳定性
快速排序的时间复杂度: 快速排序的时间复杂度在最坏情况下是 O(N2), 平均的时间复杂度是 O(N*lgN)这句话很好理解: 假设被排序的数列中有 N 个数遍历一次的时间复杂度是 O(N), 需要遍历多少次呢? 至少 lg(N+1)次, 最多 N 次
为什么最少是 lg(N+1)次? 快速排序是采用的分治法进行遍历的, 我们将它看作一棵二叉树, 它需要遍历的次数就是二叉树的深度, 而根据完全二叉树的定义, 它的深度至少是 lg(N+1)因此, 快速排序的遍历次数最少是 lg(N+1)次
为什么最多是 N 次? 这个应该非常简单, 还是将快速排序看作一棵二叉树, 它的深度最大是 N 因此, 快读排序的遍历次数最多是 N 次
快速排序的稳定性: 快速排序是不稳定的算法, 它不满足稳定算法的定义; 所谓算法稳定性指的是对于一个数列中的两个相等的数 a[i]=a[j], 在排序前, a[i]在 a[j]前面, 经过排序后 a[i]仍然在 a[j]前, 那么这个排序算法是稳定的
来源: http://www.jianshu.com/p/7e58d5be34bf