算法--排序--寻找数组内第K大的元素
发布日期:2021-07-01 03:39:32
浏览次数:2
分类:技术文章
本文共 2164 字,大约阅读时间需要 7 分钟。
此题目,需要用到快速排序里的划分数组操作:
快排参考:- 先选取一个合适的哨兵(三数取中法)
- 将数组分成三部分【小于哨兵的】【哨兵】【大于等于哨兵的】
- 然后看哨兵的下标+1 == K吗?等于就返回哨兵,不等则在一侧递归调用该划分方法
复杂度:平均情况下,遍历一次数组找到哨兵是n,下一次就是n/2,最后到1,中间最多需要k次(k=lg2n)
等比数列求和:n+n/2+n/4+n/8+…+1 所以复杂度为O(n)代码实现
/** * @description: 寻找第K大的元素 * @author: michael ming * @date: 2019/4/13 13:02 * @modified by: */#include#include #include #include "shellsort.cpp"using namespace std;void printArr(int* arr, size_t N) //打印数组{ for(int i = 0; i < N; ++i) { cout << arr[i] << " "; } cout << endl;}void generateArr(int* arr, size_t N) //生成随机数组{ srand((unsigned)time(NULL)); for(int i = 0; i < N; ++i) arr[i] = rand()%100000;}void selectMiddle(int *arr, size_t left, size_t right) //三数取中,并挪至首位{ size_t mid = left + (right-left)/2; if(arr[mid] > arr[right]) swap(arr[mid], arr[right]); if(arr[left] > arr[right]) swap(arr[left], arr[right]); if(arr[mid], arr[left]) swap(arr[mid], arr[left]);}int findkthelem(int *arr, size_t N, size_t K, size_t left, size_t right){ selectMiddle(arr, left, right); int Pval = arr[left]; size_t Pindex = left, i = left, j = right; while(i < j) //将哨兵挪至中间 { while(i < j && arr[j] > Pval) //以下两个while的顺序不可更换!!!哨兵在左边,先从右边开始比 j--; swap(arr[i],arr[j]); while(i < j && arr[i] <= Pval) i++; swap(arr[i],arr[j]); } Pindex = i; //哨兵下标 if(i+1 == K) return arr[i]; else if(i+1 < K && right-Pindex > 0) return findkthelem(arr, right-Pindex, K, Pindex+1,right); else if(i+1 > K && Pindex-left > 0) return findkthelem(arr, Pindex-left, K, left, Pindex-1);}int main(){ size_t N, K; cout << "请输入正整数N:程序将生成随机数组。" ; cin >> N; int arr[N]; generateArr(arr, N); printArr(arr, N); cout << "请输入K:程序将查找第K大的元素。"; while(true) { cin >> K; if(K > 0 && K <= N) break; cout << "K超过N了,或者为0" << endl; continue; } shellsort(arr, N); cout << "排序后数组是:" << endl; printArr(arr, N); cout << "第" << K << "大的元素是:" << findkthelem(arr,N,K,0,N-1) << endl; return 0;}
转载地址:https://michael.blog.csdn.net/article/details/89285967 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
逛到本站,mark一下
[***.202.152.39]2024年04月21日 14时05分39秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
使用 Minidumps 和 Visual Studio .NET 进行崩溃后调试
2019-05-01
Debug 和 Release 编译方式的本质区别
2019-05-01
struts返回xml数据例子
2019-05-01
内存对齐详解
2019-05-01
秋招总结(一)-C++归纳
2019-05-01
秋招总结(三)-操作系统归纳
2019-05-01
带缓冲I/O 和不带缓冲I/O的区别与联系
2019-05-01
LINUX CP命令详解
2019-05-01
source insight快捷键及使用技巧
2019-05-01
映 射 ALT 键
2019-05-01
vim使用快捷键F4生成文件头注释、F5生成main函数模板、F6生成.h文件框架模板
2019-05-01
用python解析html
2019-05-01
OV5620的视频驱动
2019-05-01
C++中两个类交叉定义或递归定义的解决办法
2019-05-01
ECharts is not Loaded解决方案
2019-05-01
echarts切换tab时,第一个图表显示,第二个图表不显示的解决办法
2019-05-01
记一次Hive 行转列 引起的GC overhead limit exceeded
2019-05-01
OpenGL ES八 - 交叉存取顶点数据
2019-05-01
crontab定时任务写法
2019-05-01