快速排序的经典实现与分析
来源:互联网 发布:php报undefined index 编辑:程序博客网 时间:2024/05/17 21:47
快速排序
快速排序是实际应用中效率最高的排序算法,它的期望时间复杂度是O(nlgn),最坏情况时间复杂度是O(n2)。虽然最坏情况复杂度很高,但是平均期望时间复杂度为O(nlgn),且常数项很小,通过随机抽样的改进后,排序的时间复杂度不会受输入数据的影响。而且算法的空间复杂度为O(lgn),能够进行原址排序。
算法代码如下所示:
int partition(vector<int>& ToBeSorted,int first,int last){ //分解步骤,将数组划分为大于x和小于x两部分,最后将x移位至中央,即x的最终正确位置,在交换元素位置时,有可能导致元素值相同的元素相对位置颠倒,因此需要快速排序是不稳定排序。 static default_random_engine e; uniform_int_distribution<> u(first,last); swap(ToBeSorted[first],ToBeSorted[u(e)]); int pivot = ToBeSorted[first]; int lhsIndex = first,rhsIndex = last + 1; while(true){ while(ToBeSorted[++lhsIndex]<pivot) if(lhsIndex == last) break; while(ToBeSorted[++rhsIndex]>pivot) if(rhsIndex == first) break; if(lhsIndex >= rhsIndex) break; swap(ToBeSorted[lhsIndex],ToBeSorted[rhsIndex]); } swap(ToBeSorted[rhsIndex],ToBeSorted[lhsIndex]); return rhsIndex; }}void QuickSort(vector<int>& ToBeSorted,int first,int last){ if (first >= last) return; //相等说明子数组只有一个元素,无需排序。 int index = partition(ToBeSorted,first,last); //每次调用Partition后,有ToBeSorted[first...index-1]<=ToBeSorted[index] <=ToBeSorted[index + 1...last],即index位置的元素到达正确位置,之后只需递归排序前半部分和后半部分即可。 QuickSort(ToBeSorted,first,index - 1); QuickSort(ToBeSorted,index + 1,last);}
上述实现有几个优点,一是随机选择pivot,可以避免对已排序的数组进行排序时,时间复杂度将退化为O(n2);其次是Partition函数中,采用两端向中间递推的方法,可以更高效的交换元素,而且对于有大量相同元素的数组,Partition函数还是能将数组分为较为均匀的两部分(遇到相同元素时,lhsIndex和rhsIndex依然会递进)。
快速排序的平均复杂度分析
由于Partition函数循环时,lhsIndex 和 rhsIndex 只遍历数组一次,且swap函数的复杂度为O(1),因此Partition函数的复杂度为O(n)。对于平均情况下的快速排序效率,我们可以假设Partition函数得到的index的值是随机的,故:
化简有:
初始条件T(1)显然为1,展开T(n)至T(1),有:
根据调和级数近似求和公式有:
Partition函数的妙用
参见博客xxx.
小结
快速排序实现非常简单,区区十几行代码就能在不利用额外存储空间的情况下,完成高效的排序,但是缺点是对于已排序的数组和大量相同元素值的数组排序时很慢,上文的实现中考虑这两点进行了改进。但是仍然存在稳定性的问题。除此之外,快速排序递归实现会产生很多小数组,每个小数组都要调用Partition函数,降低了效率。解决办法是利用插入排序排序 小数组非常高效的特点,设定一个阈值,当数组大小达到阈值时,调用插入排序。
- 快速排序的经典实现与分析
- 归并排序的经典实现与分析
- QuickSort 快速排序的分析与实现
- 快速排序算法的分析与实现
- 快速排序的经典实现
- 快速排序实现与分析
- 快速排序分析与实现
- 快速排序经典实现
- 算法设计与分析 快速排序的递归实现算法
- 快速排序方法Java实现与分析
- 快速排序分析与C语言实现
- 排序算法的C++实现与性能分析(插入排序、归并排序、快速排序、STOOGE排序、堆排序)
- 快速排序与堆排序的实现
- 经典算法与数据结构的c++实现——快速排序
- 快速排序实现分析
- 排序算法—快速排序算法分析与实现(Python)
- 快速排序的分析与优化
- 经典排序算法的设计与实现
- 互联网线上项目开发最大坑点-并发冲突处理
- 几个问题
- treeSet剖析
- 随机数函数应用于游戏(2)
- onpropertychange、oninput监听input输入框值实时变化
- 快速排序的经典实现与分析
- Java关键字之private、default、protected、public
- 正则表达式&&重写toString和equals&&包装类
- Matlab问答day7
- Java 多线程
- 程序分析1
- 如何将不同类型数据导入Elaticsearch中?
- LeetCode(371) Sum of Two Integers
- Android动画使用详解