Java 排序算法详解
排序是计算机科学中的基本操作,Java 提供了多种排序算法来满足不同的需求。常见的排序算法包括冒泡排序、选择排序、插入排序、归并排序、快速排序和堆排序。本文将逐一介绍这些排序算法及其 Java 实现。
1. 冒泡排序 (Bubble Sort)
冒泡排序是一种简单的排序算法,其基本思想是通过重复遍历待排序的元素,比较相邻元素并交换位置,直到所有元素有序。时间复杂度为 O(n^2),适合小规模数据的排序。
1.1 算法步骤
- 从头到尾遍历数组。
- 比较相邻的元素,如果前一个元素大于后一个元素,则交换它们。
- 重复步骤 1 和 2,直到没有元素需要交换为止。
1.2 Java 实现
java
复制代码
public class BubbleSort { public static void bubbleSort(int[] arr) { int n = arr.length; for (int i = 0; i < n - 1; i++) { for (int j = 0; j < n - 1 - i; j++) { if (arr[j] > arr[j + 1]) { int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } } }
2. 选择排序 (Selection Sort)
选择排序是一种简单的排序算法,其基本思想是每次从未排序的部分中选择最小(或最大)的元素,并将其放到已排序部分的末尾。时间复杂度为 O(n^2),适用于小规模数据。
2.1 算法步骤
- 从未排序的部分选择最小元素。
- 将选出的最小元素与未排序部分的第一个元素交换。
- 将已排序部分的范围扩展,重复步骤 1 和 2。
2.2 Java 实现
java
复制代码
public class SelectionSort { public static void selectionSort(int[] arr) { int n = arr.length; for (int i = 0; i < n - 1; i++) { int minIndex = i; for (int j = i + 1; j < n; j++) { if (arr[j] < arr[minIndex]) { minIndex = j; } } int temp = arr[minIndex]; arr[minIndex] = arr[i]; arr[i] = temp; } } }
3. 插入排序 (Insertion Sort)
插入排序是一种简单直观的排序算法,其基本思想是将待排序的数据分为已排序和未排序两部分,每次从未排序部分取出一个元素,将其插入到已排序部分的正确位置。时间复杂度为 O(n^2),适用于小规模数据或部分已排序的数据。
3.1 算法步骤
- 从第二个元素开始,向前与已排序部分比较。
- 如果当前元素小于已排序部分的元素,则将已排序部分的元素右移,直到找到合适的位置。
- 插入当前元素,扩展已排序部分的范围。
3.2 Java 实现
java
复制代码
public class InsertionSort { public static void insertionSort(int[] arr) { int n = arr.length; for (int i = 1; i < n; i++) { int key = arr[i]; int j = i - 1; while (j >= 0 && arr[j] > key) { arr[j + 1] = arr[j]; j--; } arr[j + 1] = key; } } }
4. 归并排序 (Merge Sort)
归并排序是一种有效的排序算法,基于分治法,其基本思想是将数组分成两个子数组,分别排序,然后将排序好的子数组合并。时间复杂度为 O(n log n),适用于大规模数据的排序。
4.1 算法步骤
- 将数组递归地分成两半,直到每个子数组只有一个元素。
- 合并已排序的子数组,形成排序好的更大子数组。
- 重复步骤 2,直到所有子数组合并成一个排序好的数组。
4.2 Java 实现
java
复制代码
public class MergeSort { public static void mergeSort(int[] arr) { if (arr.length < 2) return; int mid = arr.length / 2; int[] left = new int[mid]; int[] right = new int[arr.length - mid]; System.arraycopy(arr, 0, left, 0, mid); System.arraycopy(arr, mid, right, 0, arr.length - mid); mergeSort(left); mergeSort(right); merge(arr, left, right); } private static void merge(int[] arr, int[] left, int[] right) { int i = 0, j = 0, k = 0; while (i < left.length && j < right.length) { if (left[i] <= right[j]) { arr[k++] = left[i++]; } else { arr[k++] = right[j++]; } } while (i < left.length) arr[k++] = left[i++]; while (j < right.length) arr[k++] = right[j++]; } }
5. 快速排序 (Quick Sort)
快速排序是一种高效的排序算法,基于分治法,其基本思想是通过一个“基准”元素将数组分为两部分,一部分比基准小,另一部分比基准大,然后递归地排序这两部分。时间复杂度为 O(n log n),但在最坏情况下为 O(n^2),适用于大规模数据。
5.1 算法步骤
- 选择一个基准元素。
- 将数组分成两部分,一部分小于基准,一部分大于基准。
- 递归地对这两部分进行快速排序。
5.2 Java 实现
java
复制代码
public class QuickSort { public static void quickSort(int[] arr, int low, int high) { if (low < high) { int pi = partition(arr, low, high); quickSort(arr, low, pi - 1); quickSort(arr, pi + 1, high); } } private static int partition(int[] arr, int low, int high) { int pivot = arr[high]; int i = (low - 1); for (int j = low; j < high; j++) { if (arr[j] <= pivot) { i++; int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } int temp = arr[i + 1]; arr[i + 1] = arr[high]; arr[high] = temp; return i + 1; } }
6. 堆排序 (Heap Sort)
堆排序是一种基于堆数据结构的排序算法,时间复杂度为 O(n log n)。它的基本思想是将数组视为一个堆,通过调整堆的结构,使得每次都可以将最大元素(或最小元素)取出,重复此操作直到排序完成。
6.1 算法步骤
- 建立一个最大堆(或最小堆)。
- 取出堆顶元素,将其与堆的最后一个元素交换,然后调整堆。
- 重复步骤 2,直到堆为空。
6.2 Java 实现
java
复制代码
public class HeapSort { public static void heapSort(int[] arr) { int n = arr.length; for (int i = n / 2 - 1; i >= 0; i--) { heapify(arr, n, i); } for (int i = n - 1; i >= 0; i--) { int temp = arr[0]; arr[0] = arr[i]; arr[i] = temp; heapify(arr, i, 0); } } private static void heapify(int[] arr, int n, int i) { int largest = i; int left = 2 * i + 1; int right = 2 * i + 2; if (left < n && arr[left] > arr[largest]) { largest = left; } if (right < n && arr[right] > arr[largest]) { largest = right; } if (largest != i) { int swap = arr[i]; arr[i] = arr[largest]; arr[largest] = swap; heapify(arr, n, largest); } } }
总结
本文介绍了常见的 Java 排序算法,包括冒泡排序、选择排序、插入排序、归并排序、快速排序和堆排序。每种排序算法都有其特定的应用场景和优缺点,了解这些算法的基本原理和实现方法可以帮助你在实际编程中选择最合适的排序方法。希望本文的讲解能帮助你更好地掌握和应用这些排序算法。如果你有任何问题或需要进一步的详细说明,欢迎留言讨论!
相关文章:
Java 排序算法详解
排序是计算机科学中的基本操作,Java 提供了多种排序算法来满足不同的需求。常见的排序算法包括冒泡排序、选择排序、插入排序、归并排序、快速排序和堆排序。本文将逐一介绍这些排序算法及其 Java 实现。 1. 冒泡排序 (Bubble Sort) 冒泡排序是一种简单的排序算法…...
vue3实现拖拽移动位置,拖拽过程中鼠标松开后元素还吸附在鼠标上并随着鼠标移动
发现问题 拖拽元素移动的时候,偶尔会出现拖拽过程中鼠标松开后元素还吸附在鼠标上并随着鼠标移动,要再按一下元素才会被放置下来。但是有时就正常。 问题分析 出现该问题的原因是:这个过程会触发H5原生的拖拽事件,并且不会监听…...
没有屋檐的房子-011
棺材 (下) 时过境迁这个成语描述了前因后果的两种概念的变化,时间推延和环境的变迁。问题是,时间是什么呢?是环境变化表征了时间的推延,还是时间推延导致了环境的变化?人在多数时候,…...
Puppeteer-Cluster:并行处理网页操作的新利器
在现代Web开发和自动化测试领域,高效地处理多个网页操作任务成为了许多开发者和测试工程师的迫切需求。传统的Puppeteer工具虽然功能强大,但在处理大量并发任务时可能会显得力不从心。为此,Puppeteer-Cluster应运而生,作为一个基于…...
使用Protocol Buffers传输数据
使用 Google Protocol Buffers(ProtoBuf)与 Kafka 结合来定义和传输数据,可以确保传输数据的结构性、可扩展性和高效性。以下是一个简单的步骤指南,帮助你实现生产者和消费者。 1. 定义 ProtoBuf 消息格式 首先,你需…...
chmod修改文件权限
0 Preface/Foreword 1 chmod使用方法 1.1 修改单个文件 命令如下: sudo chmod xyz fileName xyz: x, y, z分别代表一个8进制数字(0-7) 1.2 修改文件夹 命令如下: sudo chmod -R xyz folderName...
二叉树--python
二叉树 一、概述 1、介绍 是一种非线性数据结构,将数据一分为二,代表根与叶的派生关系,和链表的结构类似,二叉树的基本单元是结点,每个节点包括值和左右子节点引用。 每个节点都有两个引用(类似于双向链…...
matlab数据批量保存为excel,文件名,行和列的名称设置
Excel文件内数据保存结果如下: Excel文件保存结果如下: 代码如下: clear;clc; for jjjj1:10 %这个可以改 jname(jjjj-1)*10; %文件名中变数 这是EXCEL文件名字的一部分 根据自己需要改 jkkkk_num2str(jname); for …...
Pygame中Sprite类实现多帧动画3-2
3.2.3 设置帧的宽度、高度、范围及列数 通过如图6所示的代码设置帧的宽度、高度、范围及列数。 图6 设置帧的宽度、高度、范围及列数的代码 其中,frame_width、frame_height、rect和columns都是MySprite类的属性,在其__init__()方法中定义,…...
C#发送正文带图片带附件的邮件
1,开启服务,获取授权码。以QQ邮箱为例: 点击管理服务,进入账号与安全页面 2,相关设置参数,以QQ邮箱为例: 登录时,请在第三方客户端的密码输入框里面填入授权码进行验证。࿰…...
【C#跨平台开发详解】C#跨平台开发技术之.NET Core基础学习及快速入门
1. C#与.NET的发展历程 C#是由Microsoft开发的现代编程语言,最初伴随着.NET Framework发布。随着技术的进步,特别是针对跨平台开发的需求,Microsoft推出了.NET Core,这是一个开源且跨平台的框架,支持Windows、macOS和…...
请解释Java中的死锁产生的原因和解决方法。什么是Java中的并发工具类?请列举几个并解释其用途。
请解释Java中的死锁产生的原因和解决方法。 Java中的死锁是指两个或两个以上的线程在执行过程中,因为争夺资源而造成的一种相互等待的现象,若无外力作用,这些线程都将无法向前推进。死锁是并发编程中常见的问题,它会导致程序运行…...
三分钟带你看懂,低代码开发赋能办公方式转变
随着技术的不断进步,企业对办公效率和灵活性的需求日益增长。低代码开发作为一种新兴的开发模式,正在改变传统的办公方式,让非技术背景的业务人员也能参与到应用的创建和维护中来。本文将带你快速了解低代码开发如何赋能办公方式的转变。 什么…...
视频剪辑软件哪个好用?11款软件轻松上手,让创意视频流畅呈现!
视频剪辑已经涉及到很多个领域,视频剪辑软件的需求也是越来越普遍了。很多朋友在日常办公学习中,经常会遇到视频剪辑的问题。借助专业的视频剪辑软件,我们可以快速的对视频进行剪辑,制作出属于自己的作品。 市面上有各种各样的视频…...
pytest二次开发:生成用例参数
pytest.fixture是一个装饰器,用于声明一个fixture。Fixture是pytest中的一个核心概念,它提供了一种将测试前的准备代码(如设置测试环境、准备测试数据等)和测试后的清理代码(如恢复测试环境、删除临时文件等࿰…...
想抹黑华为的 请换一种方式
文|琥珀食酒社 作者 | 积溪 咱能不能有点创意? 能不能换个方式? 之前我说预测过 我说华为的三折叠手机 MateXT非凡大师发布 会引来一大波华为黑 还真是被我说中了 华为MateXT刚曝光 就被黄牛炒到10多万 有人说华为要割韭菜 是电子…...
学习学习学习
1. 面试算法 算法题空间限制64MB 2x 10^7 int codetop.cc 数字中文读 🔗 kmp 奶牛生小牛问题 丑数LCR 168. 丑数 - 力扣(LeetCode) 166. 分数到小数 - 力扣(LeetCode) 小数循环节 深入解析力扣166题ÿ…...
requestAnimationFrame原理和使用
requestAnimationFrame 是一个用于在浏览器中实现高效动画的方法。它告诉浏览器你希望执行一个动画,并在下一次重绘之前调用指定的回调函数来更新动画。浏览器会自动优化动画的刷新频率,以确保动画的流畅性和性能。 原理 帧刷新:浏览器通常…...
线程的状态(java)
“苦? 何止是苦~~~~~” 本期内容来分享一下线程状态相关的知识哦!!! 对于进程来说,进程是有两种状态的。 一种是就绪状态:正在CPU上执行,或者随时可以去CPU上执行的。 另一种是阻塞状态&…...
Linux IO模型:IO多路复用
● 应用程序中同时处理多路输入输出流,若采用阻塞模式,得不到预期的目的; ● 若采用非阻塞模式,对多个输入进行轮询,但又太浪费CPU时间; ● 若设置多个进程/线程,分别处理一条数据通路ÿ…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
什么是VR全景技术
VR全景技术,全称为虚拟现实全景技术,是通过计算机图像模拟生成三维空间中的虚拟世界,使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验,结合图文、3D、音视频等多媒体元素…...
