C++实现快速选择算法查找第K大数值所在位置逻辑及平均复杂度分析逻辑 _ 逻辑【源码】

千萱大大_6682

千萱大大_6682

2026-05-09

918人浏览

原创

快速选择算法基于分治思想,通过Lomuto或Hoare分区定位第K大元素:每次分区后根据大于/等于基准的元素个数与K的关系,仅递归处理目标子区间,期望时间复杂度O(n),空间复杂度O(log n)。

c++实现快速选择算法查找第k大数值所在位置逻辑及平均复杂度分析逻辑 _ 逻辑【源码】

一、快速选择算法的基本原理

快速选择算法是基于快速排序分区思想的高效查找算法,用于在未完全排序的数组中定位第K大元素的索引位置。其核心在于每次分区后根据基准元素的位置与目标秩的关系,仅递归处理包含目标元素的一侧子区间,从而避免完整排序带来的冗余计算。

1、将数组划分为三部分:小于基准值的部分、等于基准值的部分、大于基准值的部分。

2、计算大于基准值部分的元素个数,记为greater_count;计算等于基准值部分的元素个数,记为equal_count。

3、若K ≤ greater_count,则第K大元素位于大于基准值的子区间中,递归查找该区间。

4、若K > greater_count + equal_count,则第K大元素位于小于基准值的子区间中,递归查找该区间,并更新K为K − greater_count − equal_count。

5、否则,第K大元素即为基准值本身,返回任意一个等于基准值的索引位置。

二、基于Lomuto分区方案的实现逻辑

该方案采用单指针扫描方式完成分区,代码简洁且易于理解,适用于教学和中小规模数据。分区过程中维护一个指向小于基准值区域右边界的位置变量,遍历时将小于基准的元素逐步交换至左侧。

1、选取最后一个元素作为基准(pivot)。

2、初始化索引i = low,用于标记小于基准值区域的右边界。

3、遍历j从low到high−1,若arr[j] ≥ pivot(注意:为求第K大,使用≥而非≤),则交换arr[i]与arr[j],并令i++。

4、将基准元素arr[high]与arr[i]交换,此时i为基准在分区后的确切位置。

5、比较i与目标位置target_idx(即降序排列下第K个位置,对应升序索引为n−K),决定递归方向。

三、基于Hoare分区方案的优化实现逻辑

Hoare分区通过双向扫描减少交换次数,在实际运行中通常比Lomuto方案更快。它不保证基准最终落于其排序后位置,但能更紧凑地划分大小区域,适合对性能敏感的场景。

1、选取首元素arr[low]为基准。

2、设置左右指针i = low − 1、j = high + 1。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

3、内层循环:从左向右移动i,直到arr[i] ≥ pivot;从右向左移动j,直到arr[j] ≤ pivot。

4、若i ,交换arr[i]与arr[j];否则终止分区。

5、返回j作为分界点,依据j与target_idx关系决定递归调用范围。

四、随机化基准选择以避免最坏情况

确定性选取首/尾元素作基准可能导致O(n²)时间复杂度(如已排序数组)。引入随机化可在期望意义上消除输入依赖性,使算法在任意输入下保持平均线性性能。

1、在当前子区间[low, high]中生成一个随机整数rand_idx。

2、交换arr[rand_idx]与arr[high](或arr[low],视分区方案而定)。

3、后续按原分区逻辑执行,此时基准值服从均匀分布,各次分区大小期望为1:1。

4、重复该过程于每次递归调用前,确保每层递归的基准独立同分布。

五、平均时间复杂度推导逻辑

设T(n)为处理n个元素的期望时间。每次分区后,算法以等概率落在任一位置,但仅递归处理包含第K大元素的子问题。关键观察是:每次成功分区后,剩余处理规模期望不超过3n/4。

1、定义指示变量X_i表示第i轮是否仍需继续递归,X_i = 1当且仅当当前子问题规模 > 3n/4。

2、由几何分布性质,期望递归深度为O(log n),每层分区耗时O(当前规模)。

3、总期望时间为T(n) = n + T(n/2)的主定理解,或更严格地,T(n) ≤ cn + (1/2)T(n) + (1/2)T(n),解得T(n) = O(n)。

4、常数因子隐含于分区操作的比较与交换开销中,实际系数约为3~4倍于n。

5、空间复杂度为O(log n),源于递归栈深度,尾递归优化可降至O(1)。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.14

2268

9

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

1039

6

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

447

5

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

327

5

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

426

5

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

600

5

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.21

1429

9

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

2024.03.22

1237

7

c++和c语言学习顺序推荐
c++和c语言学习顺序推荐

对于初学者,建议先学习C语言,掌握编程基础后再转入C++,便于理解面向对象编程概念。有编程经验者可直接学习C++,快速接触高级编程技术。想了解更多c++和c语言的相关内容,可以阅读本专题下面的文章。

2024.03.25

1325

9

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习