最坏情况下保证时间复杂度为N*logN的快速排序
来源:互联网 发布:淘宝助理有什么功能 编辑:程序博客网 时间:2024/04/25 18:38
快速排序的平均时间复杂度是N*logN,同时其也是实践已知的最快的通用排序算法,但是其最坏情况的时间复杂度依然是N的平方,但是只要我们对快速排序算法稍作修改,就可以保证其最坏情况的时间复杂度也是N*logN。
思路就是在递归达到一定深度后,将快速排序的递归调用改为堆排序,下面是我实现的代码,我将递归深度设置为2*ln(N),这个值也是很多算法书籍推荐的值。
#include <iostream>#include <algorithm>#include <utility>#include <cstdlib>#include <ctime>#include <random>#include <limits>#include <cmath>#include <chrono>#include <cassert>inline int left_child(int rt) { return 2 * rt + 1; }void percolate_down(int *a,int rt,int sz){int tmp = a[rt];int child = left_child(rt);for(;child < sz;rt = child,child = left_child(rt)){if(child + 1 < sz && a[child] < a[child + 1])++child;if(tmp < a[child])a[rt] = a[child];elsebreak;}a[rt] = tmp;return;}void Hsort(int *a,int sz){for(int i = sz / 2 - 1; i >= 0; --i)percolate_down(a,i,sz);for(int j = sz - 1; j > 0; --j){std::swap(a[0],a[j]);percolate_down(a,0,j);}return;}void ssort3(int *a,int s, int e){int m = (s + e) / 2;if(a[e] < a[m]) std::swap(a[e],a[m]);if(a[e] < a[s]) std::swap(a[e],a[s]);if(a[m] < a[s]) std::swap(a[m],a[s]);return;}int elect_pivot(int *a,int s,int e){ssort3(a,s,e);std::swap(a[(s + e) /2],a[e]);return a[e];}void qsort(int *a,int s,int e,int depth){if(e - s < 3){ssort3(a,s,e);return;}int i = s;int j = e;int p = elect_pivot(a,s,e);while(true){while(a[++i] < p);while(a[--j] > p);if(i < j)std::swap(a[i],a[j]);elsebreak;}std::swap(a[i],a[e]);if(depth > 0){qsort(a,s,i - 1,depth - 1);qsort(a,i + 1,e,depth - 1);}else{Hsort(a + s,i - s + 1);Hsort(a + i + 1,e - i);}return;}void Qsort(int *a,int sz){int depth = 2 * log2(sz);qsort(a,0,sz - 1,depth);return;}int da(int *a,int n){for(int i = 0; i < n; ++i){std::cout << a[i] << " ";}std::cout << std::endl;return 0;}int gen(int *a,int n){std::default_random_engine dre(time(NULL));std::uniform_int_distribution<int> uid(std::numeric_limits<int>::min(),std::numeric_limits<int>::max());while(--n >= 0){a[n] = uid(dre);}return 0;}bool chk(int *a,int n){for(int i = 0;i < n - 1; ++i)if(a[i] > a[i + 1])return false;return true;}int main(int argc,char *argv[]){if(argc != 2 && argc != 3){return 0;}int loop = atoi(argv[1]);int n = 10;if(argc == 3)n = atoi(argv[2]);int *a = new int [n];while(--loop >= 0){gen(a,n);//da(a,n);auto start = std::chrono::steady_clock::now();Qsort(a,n);auto end = std::chrono::steady_clock::now();assert(true == chk(a,n));//da(a,n);std::cout << std::chrono::duration_cast<std::chrono::duration<double>>(end - start).count() << "s" << std::endl;}delete [] a;return 0;}
阅读全文
0 0
- 最坏情况下保证时间复杂度为N*logN的快速排序
- 快速排序最坏情况下lgn的空间复杂度
- 最坏情况下为O(N)的线性时间选择
- 快排,保证最坏情况下,栈的深度为log(n)
- 关于快速排序和插入排序最坏时间复杂度为O(nlogn)的算法
- 输入n个数,最坏情况下用 n + logn
- 各排序算法最好最坏平均情况下的时间复杂度
- 几种排序在最坏和最好情况下的时间复杂度
- 最坏情况快速排序的运行时间为Ο(nlgn)的算法
- 快速排序算法在平均情况下的时间复杂度为 求详解
- 算法时间复杂度的白话解析----logN,N,N*logN
- 寻找数组中第k小的数:平均情况下时间复杂度为O(n)的快速选择算法
- 最坏情况下,合并两个大小为n的已排序数组所需要的比较次数为
- n个数,找出其中最小的k个数,写出代码,要求最坏情况下的时间复杂度不能高于O(n logk)
- 最坏情况下,合并两个大小为n的已排序数组所需要的比较次数
- 时间复杂度为O(n)的排序
- 时间复杂度为O(n)的排序
- 深入快速排序[Quick][三]最坏时间复杂度
- jquery学习之几种过滤选择器
- POJ 3190 Stall Reservations (贪心+优先队列)
- Redis数据结构和内部编码--有序集合(SortedSet)
- 从linux进程的角度看Docker
- OpenCV 图像清晰度评价(相机自动对焦)
- 最坏情况下保证时间复杂度为N*logN的快速排序
- struts2_拦截器的原理
- json基本的使用方法
- 四位密码锁*电子密码锁的设计
- leetcode 59. Spiral Matrix II
- Oracle PL/SQL开发基础(第二十一弹:基本函数)
- 葵花宝典 九 Struts 2
- Android Kotlin 用 DownloadManager 同步Json文件的实现
- cocoapods 更新指定的库