news 2026/7/21 17:32:05

快速排序算法java实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
快速排序算法java实现

快速排序是一种基于分治的排序算法,它选择一个元素作为枢轴,并通过将该枢轴置于排序后的数组中正确位置来划分。

该算法主要包含三个步骤:

选择枢轴:从数组中选择一个元素作为枢轴。枢轴的选择可以有所不同(例如,第一元素、最后元素、随机元素或中位数)。
数组划分:重新排列数组围绕枢轴。划分后,所有小于枢轴的元素位于其左侧,所有大于枢轴的元素位于其右侧。
递归调用:递归地将相同进程应用于两个分区子数组。
基础情况:当子数组中只剩一个元素时,递归停止,因为单个元素已被排序。

枢轴选择
选择枢轴有很多不同的选择。

始终选择第一个(或最后一个)元素作为枢轴。下面的实现选择了最后一个元素作为枢轴。这种方法的问题在于,最坏的情况往往是数组已经排序好。
随机选一个元素作为枢轴。这是一种首选方法,因为它没有最坏情况发生的模式。
选择中位数元素是枢轴。从时间复杂度角度看,这是一种理想的方法,因为我们可以在线性时间内找到中位数,且配分函数总是将输入数组分为两半。但平均来说需要更多时间,因为中位数的发现常数很高。
划分算法
快速排序中的密钥进程是一个分区()。 有三种常见的划分算法。所有这些算法的时间复杂度均为O(n)。

朴素划分:这里我们创建数组的副本。先放所有较小的元素,然后放更大的。最后,我们将临时数组复制回原始数组。这需要 O(n) 额外的空间。
洛穆托分区:本文中使用了该分区。这是一个简单的算法,我们跟踪较小元素的索引并不断交换。本文中我们使用它,因为它非常简单。
霍尔分区:这是所有分区中最快的。这里我们从两侧遍历数组,并在数组未分割的情况下不断交换左侧较大元素与右侧较小元素。详情请参阅Hoare对Lomuto的对决。
Lomuto划分算法的工作原理及示意图
逻辑很简单,我们从最左边的元素开始,并跟踪较小(或相等)元素的索引,作为 i。在遍历过程中,如果发现一个较小的元素,我们会将当前元素与 arr[i] 交换。否则,我们忽略当前元素。


重定向图标
让我们通过以下示例来理解分区算法的工作原理:


快速排序算法示意
在前一步,我们研究了分区过程如何根据所选枢轴重新排列数组。接下来,我们递归地将同样的方法应用到枢轴左右两个较小的子数组 。每次我们都选择新的枢轴点并再次划分数组。这个过程会持续,直到只剩下一个元素,并且总是被排序。一旦每个元素都处于正确位置,整个数组就被排序。

下图展示了递归方法如何调用枢轴左右两个较小子数组:

import java.util.Arrays; class GfG { // partition function static int partition(int[] arr, int low, int high) { // choose the pivot int pivot = arr[high]; // index of smaller element and indicates // the right position of pivot found so far int i = low - 1; // traverse arr[low..high] and move all smaller // elements to the left side. Elements from low to // i are smaller after every iteration for (int j = low; j <= high - 1; j++) { if (arr[j] < pivot) { i++; swap(arr, i, j); } } // Move pivot after smaller elements and // return its position swap(arr, i + 1, high); return i + 1; } // swap function static void swap(int[] arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } // the QuickSort function implementation static void quickSort(int[] arr, int low, int high) { if (low < high) { // pi is the partition return index of pivot int pi = partition(arr, low, high); // recursion calls for smaller elements // and greater or equals elements quickSort(arr, low, pi - 1); quickSort(arr, pi + 1, high); } } public static void main(String[] args) { int[] arr = {10, 7, 8, 9, 1, 5}; int n = arr.length; quickSort(arr, 0, n - 1); for (int val : arr) { System.out.print(val + " "); } } }

输出
1 5 7 8 9 10
快速排序的复杂度分析
时间复杂性:

最佳情况:(Ω(n log n)),当枢轴元素将数组分为两个相等的一半时发生。
平均情况 (θ(n log n)),平均而言,枢轴将数组分为两部分,但不一定相等。
最坏情况:(O(n²)),当始终选择最小或最大元素作为枢轴时(例如,已排序的数组)。
辅助空间:

最坏情况:由于不平衡划分导致递归树倾斜,需要调用栈大小为 O(n) 的 O(n)。
最佳情况:由于平衡分区,O(log n) 生成了一个具有调用栈大小为 O(log n) 的平衡递归树。
详情请参阅快速排序的时间与空间复杂性分析。

快速排序的优势
它是一种分而治之的算法,使解决问题变得更容易。
它在大数据集上效率很高。
它开销低,只需少量内存即可运行。
它对缓存友好,因为我们在同一数组上进行排序,且不会将数据复制到任何辅助数组。
在不需要稳定性的情况下,是处理大数据的最快通用算法。
它是尾部递归的,因此所有尾调用优化都是可以完成的。
快速排序的缺点
其最坏时间复杂度为 O(n)2),当枢轴选择不当时,就会发生这种情况。
对于小型数据集来说,它并不是一个好的选择。
它不是稳定排序,意味着如果两个元素键相同,快速排序时它们的相对顺序不会在排序输出中保持,因为这里我们根据枢轴的位置交换元素(不考虑它们的原始位置)。
快速排序的应用
高效地在内存中排序大型数据集。
用于库的排序函数(如 C++ std::sort 和 Java Arrays.sort 用于原语)。
在数据库中整理记录以加快搜索速度。
需要排序输入的算法中的预处理步骤(例如,二分搜索、两点技术)。
使用快速选择(Quicksort 的一种变体)找到第 k 个最小/最大的元素。
基于多个键(自定义比较器)排序对象数组。
数据压缩算法(如霍夫曼编码预处理)。
图形学和计算几何(例如凸包算法)。

编程资源 https://pan.quark.cn/s/7f7c83756948 更多资源 https://pan.quark.cn/s/bda57957c548
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/21 12:08:43

注册表单必填项测试全解析:策略、场景与最佳实践

一、必填项测试的核心价值 在用户体验与数据完整性的交汇点&#xff0c;注册表单必填项是用户转化的第一道闸门。对测试人员而言&#xff0c;这不仅关乎字段验证逻辑&#xff0c;更涉及防呆机制设计、错误恢复能力及合规性保障&#xff08;如GDPR&#xff09;。漏测一个必填项…

作者头像 李华
网站建设 2026/7/16 12:54:32

基于Spring Boot的旅游网站系统毕业论文+PPT(附源代码+演示视频)

文章目录 一、项目简介1.1 运行视频1.2 &#x1f680; 项目技术栈1.3 ✅ 环境要求说明1.4 包含的文件列表 前台运行截图后台运行截图项目部署源码下载 一、项目简介 项目基于SpringBoot框架&#xff0c;前后端分离架构&#xff0c;后端为SpringBoot前端Vue。本文旨在开发一个基…

作者头像 李华
网站建设 2026/7/21 9:34:50

图像加载手动测试流程详解

在当今数字化时代&#xff0c;图像加载功能广泛应用于Web和移动应用&#xff08;如图片画廊、电商平台和社交媒体&#xff09;&#xff0c;其性能与可靠性直接影响用户体验。手动测试作为自动化测试的重要补充&#xff0c;能有效捕捉边界情况和用户交互问题。本文针对软件测试从…

作者头像 李华
网站建设 2026/7/16 6:18:42

深度剖析高级移动端开发工程师的核心能力图谱与技术实践路径 —— 以千里马国际猎聘招聘要求为例

深圳千里马国际猎聘科技集团有限公司 高级移动端开发工程师 职位信息 【工作职责】 1. 负责 iOS 和 Android 应用的整体架构设计与核心功能开发。 2. 独立承担复杂业务模块开发,推动跨平台架构优化与性能提升。 3. 优化双平台工程架构与代码质量,提升系统的稳定性与扩展性。 …

作者头像 李华
网站建设 2026/7/20 11:46:01

『NAS』用SSH的方式连上NAS

点赞 关注 收藏 学会了 整理了一个NAS小专栏&#xff0c;有兴趣的工友可以关注一下 &#x1f449; 《NAS邪修》 有些非技术出身的工友入手NAS后&#xff0c;只用来存照片、存电影&#xff0c;却不知道开启SSH后&#xff0c;NAS能变得更强大、更好用。其实SSH一点都不复杂&am…

作者头像 李华