快速排序
2015-08-21 10:59
681 查看
快速排序是采用分治思想的。下面是分治过程的三个步骤。
分解:数组A[p…r]被划分成两个(可能空)子数组A[p…q-1]和A[q+1…r],使得A[p…q-1]中的每个元素都小于等于A[q],A[q+1…r]中每个元素都大于A[q],而下标q也在这个划分过程中进行计算。
解决:通过递归调用快速排序,对子数组A[p…q-1]和A[q+1…r]排序。
合并:因为两个子数组是就地排序的,将它们合并不需要操作。
如图所示,对于任何数组下标k,有
1) 如果p<=k<=i,则A[k]<=X。
2) 如果i+1<=k<=j-1,则A[k]>X。
3) 如果k=r,则A[k]=X。
![](https://img-blog.csdn.net/20150821110030469?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
快速排序的性能
快速排序的运行时间与划分是否对称有关,而后者又与选择了哪一个元素进行划分有关。
最坏情况的划分
快速排序的最坏情况划分发生在划分过程产生的两个区域分别包含n-1个元素和1个0元素的时候。假设算法的每一次递归调用中都出现了这种不对称划分。划分的时间代价为O(N)。因为对一个大小为0的数组进行递归调用后,返回T(0)=O(1),故算法运行时间可以递归地表示为:
T(N)=T(N-1)+T(0)+O(N)=T(N-1)+O(N)
则T(N)=O(N2)。当输入数组已经完全排好序时,快速排序的运行时间为O(N2),而在同样情况下,插入排序的运行时间为O(N)。
最佳情况的划分
其中一个子问题的大小为[n/2],另一个子问题的大小为[n/2]-1。在这种情况下,快速排序的速度快的多。这时,表达其运行时间的递归式为
T(n)<=2T(n/2)+O(N).
则T(N)=O(NlgN)。
平衡的划分
快速排序的平均情况运行时间与其最佳情况很接近。假设划分过程中总是产生9:1的划分,咋一看这种划分很不平衡,这时,快速排序时间的递归式为
T(N)<=T(9n/10)+T(n/10)+cn
在这种情况下,快速排序的运行时间为O(nlgn).
快速排序的随机化版本中
不是采用A[r]作为主元,而是从子数组A[p…r]中随机选择一个元素,即将A[r]与A[p…r]中随机选出一个元素交换
快速排序的三数取中版本
分解:数组A[p…r]被划分成两个(可能空)子数组A[p…q-1]和A[q+1…r],使得A[p…q-1]中的每个元素都小于等于A[q],A[q+1…r]中每个元素都大于A[q],而下标q也在这个划分过程中进行计算。
解决:通过递归调用快速排序,对子数组A[p…q-1]和A[q+1…r]排序。
合并:因为两个子数组是就地排序的,将它们合并不需要操作。
template<typename T> int PARTIRION(T array[],int p,int r) { T x = array[r]; int i = p - 1; int j = p; for (; j < r; j++) { if (array[j] <= x) { i++; swap(array[i], array[j]); } } swap(array[i + 1], array[r]); return i + 1; } template<typename T> void Quick_Sort(T array[],int p,int r) { if (p < r) { int q = PARTIRION(array, p, r); Quick_Sort(array, p, q - 1); Quick_Sort(array, q+1, r); } }
如图所示,对于任何数组下标k,有
1) 如果p<=k<=i,则A[k]<=X。
2) 如果i+1<=k<=j-1,则A[k]>X。
3) 如果k=r,则A[k]=X。
快速排序的性能
快速排序的运行时间与划分是否对称有关,而后者又与选择了哪一个元素进行划分有关。
最坏情况的划分
快速排序的最坏情况划分发生在划分过程产生的两个区域分别包含n-1个元素和1个0元素的时候。假设算法的每一次递归调用中都出现了这种不对称划分。划分的时间代价为O(N)。因为对一个大小为0的数组进行递归调用后,返回T(0)=O(1),故算法运行时间可以递归地表示为:
T(N)=T(N-1)+T(0)+O(N)=T(N-1)+O(N)
则T(N)=O(N2)。当输入数组已经完全排好序时,快速排序的运行时间为O(N2),而在同样情况下,插入排序的运行时间为O(N)。
最佳情况的划分
其中一个子问题的大小为[n/2],另一个子问题的大小为[n/2]-1。在这种情况下,快速排序的速度快的多。这时,表达其运行时间的递归式为
T(n)<=2T(n/2)+O(N).
则T(N)=O(NlgN)。
平衡的划分
快速排序的平均情况运行时间与其最佳情况很接近。假设划分过程中总是产生9:1的划分,咋一看这种划分很不平衡,这时,快速排序时间的递归式为
T(N)<=T(9n/10)+T(n/10)+cn
在这种情况下,快速排序的运行时间为O(nlgn).
快速排序的随机化版本中
不是采用A[r]作为主元,而是从子数组A[p…r]中随机选择一个元素,即将A[r]与A[p…r]中随机选出一个元素交换
快速排序的三数取中版本
<span style="color:#000000;">template<typename T> int PARTIRION(T array[],int p,int r) { int Center = (p + r) / 2; if (array[p] > array[Center]) swap(array[p], array[Center]); if (array[p] > array[r]) swap(array[p], array[r]); if (array[Center] < array[r]) swap(array[Center], array[r]); T x = array[r]; int i = p - 1; int j = p; for (; j < r; j++) { if (array[j] <= x) { i++; swap(array[i], array[j]); } } swap(array[i + 1], array[r]); return i + 1; } template<typename T> void Quick_Sort(T array[],int p,int r) { if (p < r) { int q = PARTIRION(array, p, r); Quick_Sort(array, p, q - 1); Quick_Sort(array, q+1, r); } }</span>
相关文章推荐
- Eclipse 下利用 gradle 构建系统
- Centos 使用YUM安装MariaDB
- 软件的概要设计都需要做什么
- eclipse代码检查工具-FindBugs介绍
- ndroid调用平台功能具体技巧分享
- 页面中插入百度地图(使用百度地图API)
- javascript 正则表达式判断只能是中文、英文或者中文加英文
- HDU5414——字符串思维题——CRB and String
- 使用Telnet访问Memcached
- CMFCEditBrowseCtrl的简单使用
- Android之Adapter用法总结
- [Leetcode]Majority Element II
- Centos7安装配制VSftp权限(二)
- mongodb文档概念
- HDOJ 1874 畅通工程续【Floyd】
- ViewGroup的onMeasure和onLayout分析
- 用筛选法求100以内的素数(数组)
- 网络socket编程指南
- 【Python】变量数值交换、判断数组是否含有某个元素
- linux改变文件文件的大小