当前位置: 首页 > java >正文

【常用算法:排序篇】3.极速排序秘籍:快排三大优化与高效选择算法

1、高效选择算法

1. 快速选择算法(QuickSelect)

  • 核心思想:基于快速排序的 partition 过程,无需完全排序即可找到第k小(大)元素
  • 时间复杂度:平均 O(n),最坏 O(n²),但通过优化可趋近 O(n)
  • 应用场景:解决 Top-K 问题(如查找前 K 小元素)。

代码示例

def quick_select(arr, l, r, k):if l == r:return arr[l]pivot = partition(arr, l, r)if k == pivot:return arr[pivot]elif k < pivot:return quick_select(arr, l, pivot-1, k)else:return quick_select(arr, pivot+1, r, k)

在这里插入图片描述


2. BFPRT算法(中位数的中位数算法)

  • 目标:保证最坏情况下 O(n) 时间复杂度的选择算法。
  • 步骤:
    1. 将数组划分为 n/5 组,每组5个元素。
    2. 对每组求中位数,形成新的中位数数组。
    3. 递归调用BFPRT算法,找到中位数数组的中位数 M
    4. 用 M 作为基准值分区,缩小问题规模。
  • 优势:确定性算法,严格保证 O(n) 时间复杂度。
  • 代码复杂度:实现较复杂,需处理分组和递归逻辑。

2、快速排序三大优化

优化一:单边递归法(减少递归调用)

  • 原理:将左右两边的递归转为循环处理左半边,仅递归处理右半边,减少函数调用开销
  • 代码示例
def quick_sort(arr, l, r):while l < r:pivot = partition(arr, l, r)quick_sort(arr, pivot+1, r)  # 递归处理右半边r = pivot - 1                # 循环处理左半边

在这里插入图片描述

优化二:三点取中法(优化基准值选择)

  • 原理:选取头、尾、中间三个元素的中位数作为基准值,避免最坏时间复杂度
  • 实现逻辑
def choose_pivot(arr, l, r):mid = (l + r) // 2candidates = sorted([arr[l], arr[mid], arr[r]])return candidates[1]  # 返回中间值

在这里插入图片描述

优化三:双指针 Partition(减少比较次数)

  • 原理:头尾指针同时扫描,交换不满足条件的元素,减少元素比较次数
  • 代码示例
def partition(arr, l, r):pivot = choose_pivot(arr, l, r)i, j = l, rwhile i <= j:while arr[i] < pivot: i += 1  # 找左边大于基准的元素while arr[j] > pivot: j -= 1  # 找右边小于基准的元素if i <= j:arr[i], arr[j] = arr[j], arr[i]i += 1j -= 1return i  # 返回分界点

在这里插入图片描述


3、性能对比与选型建议

方法时间复杂度优势适用场景
快速选择算法O(n)无需完全排序,高效查找第k元素Top-K问题、中位数查找
单边递归法O(nlogn)减少函数调用,提升运行速度大规模数据排序
三点取中法O(nlogn)避免最坏情况,稳定性高数据分布不均的场景
双指针PartitionO(nlogn)减少比较次数,提升局部效率高频次排序操作

🚀 4、实战技巧

  1. Top-K问题:优先使用快速选择算法,时间复杂度最优。
  2. 性能瓶颈:若数据规模大且重复排序,采用单边递归 + 三点取中法组合优化。
  3. 代码简洁性:双指针 Partition 实现更简洁,适合面试手撕代码场景。

💡 总结:通过单边递归减少调用、三点取中提升稳定性、双指针优化局部效率,快速排序性能实现质的飞跃!掌握这些技巧,轻松应对算法面试与工程优化挑战!

http://www.xdnf.cn/news/5164.html

相关文章:

  • 嵌入式学习--江协51单片机day4
  • 华为云服务器核心用途全景解析:从基础服务到行业革新​​
  • AIGC时代大模型幻觉问题深度治理:技术体系、工程实践与未来演进
  • (九)什么是传输线模型? 进入传输线模型的条件? why讯号反射(reflection)? 各种阻抗匹配方式与差异?
  • 递归函数(斐波那契数列0,1,1,2,3,5,8,13,21,34,55...)
  • AWS SNS:解锁高并发消息通知与系统集成的云端利器
  • 【Linux】基础 IO(一)
  • Satori:元动作 + 内建搜索机制,实现超级推理能力
  • Proser:在使用中改进
  • 使用FastAPI和React以及MongoDB构建全栈Web应用02 前言
  • 什么是向量数据库?向量数据库和关系数据库有什么区别?
  • Java常用类概述
  • C语言_函数hook_LD_PRELOAD原理和示例
  • 阿里云购买ECS 安装redis mysql nginx jdk 部署jar 部署web
  • Docker磁盘空间不足问题
  • 【算法-哈希表】常见算法题的哈希表套路拆解
  • QMK自定义4*4键盘固件创建教程:最新架构详解
  • 《解锁React Native与Flutter:社交应用启动速度优化秘籍》
  • VSCode-插件:codegeex:ai coding assistant / 清华智普 AI 插件
  • Linux:进程间通信---消息队列信号量
  • jMeter压测环境部署JDK+Groovy+JMeter+Proto+IntelliJ IDEA
  • Ubuntu 安装 HAProxy
  • 从代码学习深度学习 - 语义分割和数据集 PyTorch版
  • 图像处理篇---MJPEG视频流处理
  • .Net HttpClient 管理客户端(初始化与生命周期管理)
  • Level1.5算数运算符与赋值运算符
  • Python----神经网络(《Deep Residual Learning for Image Recognition》论文和ResNet网络结构)
  • 内网穿透系列三:开源本地服务公网映射工具 tunnelmole
  • 订单重复扣款故障分析:如何保障支付系统的幂等性
  • kotlin flow防抖