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

Java 实现快速排序算法:一条快速通道,分而治之

大家好,今天我们来聊聊快速排序(QuickSort)算法,这个经典的排序算法被广泛应用于各种需要高效排序的场景。作为一种分治法(Divide and Conquer)算法,快速排序的效率在平均情况下非常高,是大多数排序算法中的“黄金选手”。那么,让我们一起来了解如何在 Java 中实现快速排序吧!

一、什么是快速排序?

快速排序是一种基于分治法的排序算法,它的基本思想是通过选择一个“基准”元素,将待排序的数组分成两个子数组,使得一个子数组的所有元素都小于基准元素,另一个子数组的所有元素都大于基准元素。然后对这两个子数组递归执行快速排序,最终完成排序。

快速排序的步骤:
  1. 从数组中选择一个元素作为“基准”(pivot)。
  2. 将数组中所有比基准小的元素移到基准的左边,比基准大的元素移到基准的右边。
  3. 递归地对基准左边和右边的子数组进行排序。
  4. 当子数组的大小为 1 或者 0 时,停止递归,因为它们已经是有序的。

二、快速排序的时间复杂度

快速排序的时间复杂度是O(n log n),但在最坏情况下(比如每次选取的基准元素都是最小或最大的元素),它的时间复杂度会退化到O(n²)。然而,在平均情况下,快速排序的表现非常优秀,因此它通常被认为是高效的排序算法之一。

  • 最好和平均时间复杂度:O(n log n)
  • 最坏时间复杂度:O(n²)
  • 空间复杂度:O(log n)

三、Java 快速排序的实现

在 Java 中实现快速排序,我们需要编写一个递归函数来进行分割和排序。具体步骤如下:

  1. 选择基准元素:常见的选择方式是选取数组的第一个元素、最后一个元素、或随机选择一个元素作为基准。
  2. 划分数组:通过一个指针将数组分成两个部分,一部分小于基准,另一部分大于基准。
  3. 递归排序子数组:对左边和右边的子数组分别递归执行快速排序。

下面是 Java 实现快速排序的代码:

public class QuickSort {public static void sort(int[] arr, int left, int right) {//递归跳出条件:每个左右子数组的长度为1,大于和等于都要有if (left >= right) {return;}//基准数int base = arr[left];int i = left;int j = right;while (i < j) {//注意先从右向左找,注意没有等号while (arr[j] > base && j > i) {j--;}//再从左往右找,注意要有等号while (arr[i] <= base && i < j) {i++;}//如果因为i = j跳出循环,那么没必要进行交换if (i < j) {//交换两元素位置int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}//交换基准与i=j的位置arr[left] = arr[i];arr[i] = base;//左右子数组递归排序sort(arr,left, i - 1);sort(arr, i + 1, right);}public static void main(String[] args) {int[] arr = {10, 7, 8, 9, 1, 5};System.out.println("原始数组:");printArray(arr);// 调用快速排序quickSort(arr, 0, arr.length - 1);System.out.println("排序后的数组:");printArray(arr);}
}

四、代码解析

  1. quickSort 方法:这是快速排序的递归入口函数。它接收一个数组和数组的下标 lowhigh,表示待排序数组的范围。如果 low 小于 high,就调用 partition 方法来划分数组并递归排序。

  2. partition 方法:该方法用于选择基准元素并将数组划分为两部分:

    • 所有小于基准的元素排在基准的左边。
    • 所有大于基准的元素排在基准的右边。 最后,基准元素会被放到它的正确位置,并返回该位置的索引。
  3. swap 方法:用于交换数组中两个元素的位置。

  4. printArray 方法:用于打印数组,便于观察排序结果。

五、输出结果

假设我们使用的数组是 {10, 7, 8, 9, 1, 5},那么运行上述代码后的输出将会是:

原始数组:
10 7 8 9 1 5 
排序后的数组:
1 5 7 8 9 10 

可以看到,数组成功地按照从小到大的顺序进行了排序。

六、优化与扩展

  1. 选择基准优化

    • 在选择基准时,避免总是选取第一个或最后一个元素,可以通过三数取中法来选择基准元素,从而避免在已经部分有序的数组中出现最坏情况(O(n²))。

    示例:

    int mid = low + (high - low) / 2;
    int pivot = medianOfThree(arr[low], arr[mid], arr[high]);
    
  2. 尾递归优化

    快速排序是递归的,递归深度可能较深。通过尾递归优化,可以将较小的子数组放在栈中,而将较大的子数组先处理,减少栈的深度。
  3. 非递归实现

    快速排序也可以通过栈实现非递归版本,避免递归过深导致栈溢出。

七、小结

快速排序是一个高效的排序算法,通过分治法将问题逐步简化。尽管它在最坏情况下的时间复杂度是 O(n²),但在平均情况下,其表现非常优异,尤其是在处理大量数据时。如果能优化基准选择,快速排序的效率会进一步提升。希望通过本文的介绍,你对快速排序有了更深入的了解,并且能够在 Java 中轻松实现这一经典算法!

相关文章:

Java 实现快速排序算法:一条快速通道,分而治之

大家好&#xff0c;今天我们来聊聊快速排序&#xff08;QuickSort&#xff09;算法&#xff0c;这个经典的排序算法被广泛应用于各种需要高效排序的场景。作为一种分治法&#xff08;Divide and Conquer&#xff09;算法&#xff0c;快速排序的效率在平均情况下非常高&#xff…...

20250223下载并制作RTX2080Ti显卡的显存的测试工具mats

20250223下载并制作RTX2080Ti显卡的显存的测试工具mats 2025/2/23 23:23 缘起&#xff1a;我使用X99的主板&#xff0c;使用二手的RTX2080Ti显卡【显存22GB版本&#xff0c;准备学习AI的】 但是半年后发现看大码率的视频容易花屏&#xff0c;最初以为是WIN10经常更换显卡/来回更…...

element-ui的组件使用

1. 安装 Element UI&#xff08;在文件夹最上面输入cmd进入dos窗口&#xff0c;然后输入安装指令 npm install element-ui --save&#xff09; 2.在main.js文件全局引入(main.js文件负责 全局注册 )&#xff0c;在该文件注册的所有组件在其他文件都能直接调用&#xff0c;一般…...

医疗AI领域中GPU集群训练的关键技术与实践经验探究(上)

医疗AI领域中GPU集群训练的关键技术与实践经验探究(上) 一、引言 1.1 研究背景与意义 在科技飞速发展的当下,医疗 AI 作为人工智能技术与医疗领域深度融合的产物,正引领着医疗行业的深刻变革。近年来,医疗 AI 在疾病诊断、药物研发、健康管理等诸多方面取得了显著进展,…...

详解Redis淘汰策略

引言 Redis 是一个高性能的内存数据库&#xff0c;广泛应用于缓存系统、消息队列等场景。当 Redis 的内存达到限制时&#xff0c;需要根据一定的策略来淘汰数据&#xff0c;以便腾出空间给新数据。本文将深入解析 Redis 的内存淘汰机制&#xff0c;帮助更好地配置 Redis&#…...

HarmonyOS 5.0应用开发——鸿蒙接入高德地图实现POI搜索

【高心星出品】 文章目录 鸿蒙接入高德地图实现POI搜索运行结果&#xff1a;准备地图编写ArkUI布局来加载HTML地图 鸿蒙接入高德地图实现POI搜索 在当今数字化时代&#xff0c;地图应用已成为移动设备中不可或缺的一部分。随着鸿蒙系统的日益普及&#xff0c;如何在鸿蒙应用中…...

nginx关于配置SSL后启动失败原因分析

在配置SSL后&#xff0c;启动./nginx失败&#xff0c;报错提示如下&#xff1a; nginx: [emerg] the "ssl" parameter requires ngx_http_ssl_module in /usr/local/nginx-1.27.4/conf/nginx.conf:36 这个错误提示表在配置nginx启用SSL时&#xff0c;nginx未启用 ng…...

【自学嵌入式(9)ESP8266网络服务器的使用】

ESP8266网络服务器的使用 ESP8266WiFi 库① WiFiClass② WiFiClient③ WiFiServer④ WiFiUDP ESP8266WiFiMulti 库① WiFiMulti ESP8266WebServer 库① ESP8266WebServer 网络服务器实例在浏览器中控制ESP8266指示灯将开发板引脚状态显示在网页中 在之前的文章中&#xff0c;曾…...

危化品经营单位安全管理人员的职责及注意事项

危化品经营单位安全管理人员肩负着保障经营活动安全的重要责任&#xff0c;以下是其主要职责及注意事项&#xff1a; 职责 1. 安全制度建设与执行&#xff1a;负责组织制定本单位安全生产规章制度、操作规程和生产安全事故应急救援预案&#xff0c;确保这些制度符合国家相关法…...

项目实战--网页五子棋(匹配模块)(5)

上期我们实现了websocket后端的大部分代码&#xff0c;这期我们实现具体的匹配逻辑 1. 定义Mather类 我们新建一个Matcher类用来实现匹配逻辑 Component public class Matcher {//每个匹配队列代表不同的段位,这里约定每一千分为一个段位private ArrayList<Queue<User…...

mysql 迁移到人大金仓数据库

我是在windows上安装了客户端工具 运行数据库迁移工具 打开 在浏览器输入http://localhost:54523/ 账号密码都是kingbase 添加mysql源数据库连接 添加人大金仓目标数据库 添加好的两个数据库连接 新建迁移任务 选择数据库 全选 迁移中 如果整体迁移不过去可以单个单个或者几个…...

uniapp 网络请求封装(uni.request 与 uView-Plus)

一、背景 在开发项目中&#xff0c;需要经常与后端服务器进行交互&#xff1b;为了提高开发效率和代码维护性&#xff0c;以及降低重复性代码&#xff0c;便对网络请求进行封装统一管理。 二、创建环境文件 2.1、根目录新建utils文件夹&#xff0c;utils文件夹内新建env.js文…...

计算机网络与通讯知识总结

计算机网络与通讯知识总结 基础知识总结 1)FTP:文件传输 SSH:远程登录 HTTP:网址访问 2)‌交换机 定义‌:一种基于MAC地址实现局域网(LAN)内数据高速转发的网络设备,可为接入设备提供独享通信通道‌。 -‌ 核心功能‌: 1.数据链路层(OSI第二层)工作,通过MAC地址…...

DPVS-2:单臂负载均衡测试

上一篇编译安装了DPVS&#xff0c;这一篇开启DPVS的负载均衡测试 &#xff1a; 单臂 FULL NAT模式 拓扑-单臂 单臂模式 DPVS 单独物理机 CLINET&#xff0c;和两个RS都是另一个物理机的虚拟机&#xff0c;它们网卡都绑定在一个桥上br0 &#xff0c; 二层互通。 启动DPVS …...

open webui 部署 以及解决,首屏加载缓慢,nginx反向代理访问404,WebSocket后端服务器链接失败等问题

项目地址&#xff1a;GitHub - open-webui/open-webui: User-friendly AI Interface (Supports Ollama, OpenAI API, ...) 选择了docker部署 如果 Ollama 在您的计算机上&#xff0c;请使用以下命令 docker run -d -p 3000:8080 --add-hosthost.docker.internal:host-gatewa…...

交通物联网:概念、历史、现状与展望

交通物联网&#xff1a;概念、历史、现状与展望 李升伟 李昱均 一、概念 交通物联网&#xff08;Internet of Vehicles, IoV&#xff09;是物联网&#xff08;IoT&#xff09;在交通领域的延伸&#xff0c;旨在通过信息传感设备&#xff0c;实现车、路、人、云之间的全方位连…...

如何实现应用程序与中间件的类进行隔离

以下是一些可以实现类似阿里巴巴 Pandora 功能的框架和工具&#xff0c;这些项目可以帮助你实现类隔离以及中间件和应用的 JAR 包隔离&#xff1a; 1. Pandora Boot Pandora Boot 是阿里巴巴开源的一个基于 Pandora 的轻量级隔离容器&#xff0c;用于管理第三方包&#xff0c…...

MySQL 数据库基础

1. MySQL 数据库基础 在这一部分&#xff0c;我们将学习 MySQL 的基本概念和常见的数据库操作&#xff0c;帮助你掌握如何创建数据库、表&#xff0c;并进行数据的增、删、改操作。同时&#xff0c;我们还会探讨一些常见的错误示例及其原因&#xff0c;帮助你避免常见的陷阱。…...

微服务即时通信系统---(三)框架学习

目录 brpc RPC框架 核心概念 工作原理 介绍 安装 头文件包含和编译时指明库 类与接口介绍 日志输出类与接口 protobuf类与接口 Closure类 RpcController类 服务端类与接口 ServerOptions类 Server类 ClosureGuard类 HttpHeader类 Controller类 客户端类与…...

解决Spring Data JPA set值后自动更新到数据库问题

出现问题&#xff1a; 通过EntityManager查询出数据保存到对象中&#xff0c;但是向对象set值后就自动更新到数据库中去了。 Hibernate对象的三种状态 1、瞬时态&#xff1a;对象刚new出来&#xff0c;还未通过save方法保存到数据库&#xff0c;或通过游离态对象、持久化态对象…...

UE建模工具实战指南:从基础操作到高效技巧

1. UE建模工具入门&#xff1a;认识基础操作 第一次打开UE建模工具时&#xff0c;很多人会被密密麻麻的按钮吓到。别担心&#xff0c;我们先从最常用的几个功能开始。就像学做菜要先认识锅碗瓢盆一样&#xff0c;掌握这些基础工具&#xff0c;你就能完成80%的建模工作了。 **晶…...

逆向思维:不写爬虫,用FFmpeg一键下载微信小程序里的M3U8视频流

逆向思维&#xff1a;用FFmpeg高效下载微信小程序M3U8视频流 每次遇到需要保存微信小程序里的视频时&#xff0c;大多数开发者第一反应就是写爬虫——抓包分析、下载TS片段、合并文件&#xff0c;一套流程下来至少得折腾半小时。但今天我要分享一个更聪明的解决方案&#xff1a…...

26HVV行动 初 中 高 级人员招聘

一、HW人员要求及详细介绍 原文地址&#xff1a;https://mp.weixin.qq.com/s/vzRwUhtWj8tfibZFS7YfoA HW介绍 HW&#xff08;网络安全护网行动&#xff09;是国家关键信息基础设施安全攻防演练行动&#xff0c;旨在通过实战化攻防对抗提升行业网络安全防护能力。 城市&…...

抖音去水印神器:一键批量保存用户全部作品的终极解决方案

抖音去水印神器&#xff1a;一键批量保存用户全部作品的终极解决方案 【免费下载链接】TikTokDownload 抖音去水印批量下载用户主页作品、喜欢、收藏、图文、音频 项目地址: https://gitcode.com/gh_mirrors/ti/TikTokDownload 还在为抖音上精彩的内容无法完整保存而烦恼…...

2026最权威的五大降AI率方案推荐榜单

Ai论文网站排名&#xff08;开题报告、文献综述、降aigc率、降重综合对比&#xff09; TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 在内容创作的进程当中&#xff0c;降低 AIGC 率这个目标&#xff0c;得从语言风格与结构逻辑…...

PatchCore算法升级手记:当ViT(CaiT)遇见工业缺陷检测,效果提升了多少?

PatchCore算法升级手记&#xff1a;当ViT遇见工业缺陷检测 在工业质检领域&#xff0c;微小的表面缺陷往往隐藏在复杂的纹理背景中&#xff0c;传统CNN架构的局部感受野限制使其难以捕捉全局异常模式。最近半年&#xff0c;我们团队针对PatchCore这一经典无监督异常检测框架进行…...

OpenClaw 这样卸载才够干净,全程 5 大步

大家好&#xff0c;这里是小凡 AI 研习社&#xff0c;我是小凡。 之前在《安装教程》和《安装教程补充版》中&#xff0c;我们详细讲解了 OpenClaw 的安装流程&#xff0c;本节课就来完整介绍它的卸载方法。 一、哪些地方有 OpenClaw 的相关内容&#xff1f; OpenClaw 要想卸…...

Unity新手避坑指南:用C#脚本动态修改材质和Shader,别再搞混material和sharedMaterial了

Unity材质控制深度解析&#xff1a;从内存管理到动态效果实战 在Unity开发中&#xff0c;材质(Material)和着色器(Shader)的控制是创建动态视觉效果的核心技能。许多开发者在使用C#脚本修改材质属性时&#xff0c;常常陷入material和sharedMaterial的混淆陷阱&#xff0c;导致内…...

告别裸机思维:用STM32CubeMX和HAL库快速搭建串口调试打印框架(Keil5工程)

STM32CubeMX与HAL库实战&#xff1a;构建高效串口调试框架 在嵌入式开发中&#xff0c;串口调试是最基础却至关重要的技能。想象一下&#xff0c;当你的代码在目标板上运行时&#xff0c;如何快速定位问题&#xff1f;如何验证变量值是否符合预期&#xff1f;一个可靠的串口打…...

后端中使用SDK原生方法上链【FISCO BCOS】

创建Client的方式&#xff1a;先配置文件路径&#xff1a;初始化SDK并获取Client&#xff1a;BcosSDK&#xff1a;总管理工具Client&#xff1a;与区块链交互的核心对象群组1&#xff1a;链接到群组1的链二、三种链上合约函数调用方法 两种链状态信息获取方法获取客…...