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 中轻松实现这一经典算法!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/71917.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入解析 Spring 中的 BeanDefinition 和 BeanDefinitionRegistry

在 Spring 框架中&#xff0c;BeanDefinition 和 BeanDefinitionRegistry 是两个非常重要的概念&#xff0c;它们共同构成了 Spring IoC 容器的核心机制。本文将详细介绍这两个组件的作用、实现以及它们之间的关系。 一、BeanDefinition&#xff1a;Bean 的配置描述 1.1 什么…

《OpenCV》——光流估计

什么是光流估计&#xff1f; 光流估计的前提&#xff1f; 基本假设 亮度恒定假设&#xff1a;目标像素点的亮度在相邻帧之间保持不变。这是光流计算的基础假设&#xff0c;基于此可以建立数学方程来求解光流。时间连续或运动平滑假设&#xff1a;相邻帧之间的时间间隔足够小&a…

信息系统的安全防护

文章目录 引言**1. 物理安全****2. 网络安全****3. 数据安全****4. 身份认证与访问控制****5. 应用安全****6. 日志与监控****7. 人员与管理制度****8. 其他安全措施****9. 安全防护框架**引言 从技术、管理和人员三个方面综合考虑,构建多层次、多维度的安全防护体系。 信息…

如何进行OceanBase 运维工具的部署和表性能优化

本文来自OceanBase 用户的实践分享 随着OceanBase数据库应用的日益深入&#xff0c;数据量不断攀升&#xff0c;单个表中存储数百万乃至数千万条数据的情况变得愈发普遍。因此&#xff0c;部署专门的运维工具、实施针对性的表性能优化策略&#xff0c;以及加强指标监测工作&…

如何防止 Instagram 账号被盗用:安全设置与注意事项

如何防止 Instagram 账号被盗用&#xff1a;安全设置与注意事项 在这个数字化时代&#xff0c;社交媒体平台如 Instagram 已成为我们日常生活的一部分。然而&#xff0c;随着网络犯罪的增加&#xff0c;保护我们的在线账户安全变得尤为重要。以下是一些关键的安全设置和注意事…

Redis|复制 REPLICA

文章目录 是什么能干嘛怎么玩案例演示复制原理和工作流程复制的缺点 是什么 官网地址&#xff1a;https://redis.io/docs/management/replication/Redis 复制机制用于将数据从一个主节点&#xff08;Master&#xff09;复制到一个或多个从节点&#xff08;Slave&#xff09;&a…

对象存储之Ceph

Ceph 对象存储概述 Ceph 是一个开源分布式存储系统&#xff0c;旨在提供高度可扩展、高度可用、容错、性能优异的存储解决方案。它结合了块存储、文件系统存储和对象存储的功能&#xff0c;且在设计上具有极高的可扩展性和灵活性。 在 Ceph 中&#xff0c;对象存储&#xff0…

Document对象

DOM4j中&#xff0c;获得Document对象的方式有三种&#xff1a; 1.读取XML文件,获得document对象 SAXReader reader new SAXReader(); Document document reader.read(new File("input.xml")); 2.解析XML形式的文本,得到document对象…

树莓集团南京产业园再布局:深入剖析背后逻辑

在产业园区蓬勃发展的当下&#xff0c;树莓集团在南京的产业园再布局行动备受瞩目。这一举措并非偶然&#xff0c;其背后蕴含着深刻且多元的战略逻辑。 一、顺应区域产业发展趋势 南京作为长三角地区的重要城市&#xff0c;产业基础雄厚且多元。近年来&#xff0c;南京大力推动…

Pytorch实现之脑电波图像生成

简介 简介:采用双GAN模型架构来生成脑电波与目标图像。 论文题目:Image Generation from Brainwaves using Dual Generative Adversarial Training(使用双生成对抗训练的脑电波图像生成) 会议:IEEE Global Conference on Consumer Electronics (GCCE) 摘要:表示通过无…

HTML解析 → DOM树 CSS解析 → CSSOM → 合并 → 渲染树 → 布局 → 绘制 → 合成 → 屏幕显示

一、关键渲染流程 解析 HTML → 生成 DOM 树 浏览器逐行解析 HTML&#xff0c;构建**DOM&#xff08;文档对象模型&#xff09;**树状结构 遇到 <link> 或 <style> 标签时会暂停 HTML 解析&#xff0c;开始加载 CSS 解析 CSS → 生成 CSSOM 将 CSS 规则解析为**…

剑指offer - 面试题11 旋转数组的最小数字

题目链接&#xff1a;旋转数组的最小数字 第一种&#xff1a;正确写法&#xff08;num[m]和nums[r]比较&#xff09; class Solution { public:/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可** * param nums int整型v…

Spring源码分析の循环依赖

文章目录 前言一、循环依赖问题二、循环依赖的解决三、整体流程分析 前言 常见的可能存在循环依赖的情况如下&#xff1a; 两个bean中互相持有对方作为自己的属性。   类似于&#xff1a; 两个bean中互相持有对方作为自己的属性&#xff0c;且在构造时就需要传入&#xff1a…

Docker 部署 Jenkins持续集成(CI)工具

[TOC](Docker 部署 Jenkins持续集成(CI)工具) 前言 Jenkins 是一个流行的开源自动化工具&#xff0c;广泛应用于持续集成&#xff08;CI&#xff09;和持续交付&#xff08;CD&#xff09;的环境中。通过 Docker 部署 Jenkins&#xff0c;可以简化安装和配置过程&#xff0c;并…

《Effective Objective-C》阅读笔记(中)

目录 接口与API设计 用前缀避免命名空间冲突 提供“全能初始化方法” 实现description方法 尽量使用不可变对象 使用清晰而协调的命名方式 方法命名 ​编辑类与协议命名 为私有方法名加前缀 理解OC错误模型 理解NSCopying协议 协议与分类 通过委托与数据源协议进行…

C++程序员内功修炼——Linux C/C++编程技术汇总

在软件开发的宏大版图中&#xff0c;C 语言宛如一座巍峨的高山&#xff0c;吸引着无数开发者攀登探索。而 Linux 操作系统&#xff0c;以其开源、稳定、高效的特性&#xff0c;成为了众多开发者钟爱的开发平台。将 C 与 Linux 相结合&#xff0c;就如同为开发者配备了一把无坚不…

数据库索引:缺点与类型全解析

在数据库的世界里&#xff0c;索引就像是一本书的目录&#xff0c;它能帮助我们快速定位到所需的数据&#xff0c;极大地提升查询效率。然而&#xff0c;就如同任何事物都有两面性一样&#xff0c;索引也并非完美无缺。今天&#xff0c;我们就来深入探讨一下索引的缺点以及常见…

【python】提取word\pdf格式内容到txt文件

一、使用pdfminer提取 import os import re from pdfminer.high_level import extract_text import docx2txt import jiebadef read_pdf(file_path):"""读取 PDF 文件内容:param file_path: PDF 文件路径:return: 文件内容文本"""try:text ext…

嵌入式八股文(五)硬件电路篇

一、名词概念 1. 整流和逆变 &#xff08;1&#xff09;整流&#xff1a;整流是将交流电&#xff08;AC&#xff09;转变为直流电&#xff08;DC&#xff09;。常见的整流电路包括单向整流&#xff08;二极管&#xff09;、桥式整流等。 半波整流&#xff1a;只使用交流电的正…

精选案例展 | 智己汽车—全栈可观测驱动智能化运营与成本优化

本案例为“观测先锋 2024 可观测平台创新应用案例大赛”精选案例&#xff0c;同时荣获IT168“2024技术卓越奖评选-年度创新解决方案”奖。 项目背景 近年来&#xff0c;中国汽车行业进入转型升级阶段&#xff0c;智能网联技术成为行业发展的核心。车联网、自动驾驶等技术的加速…