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

Java 排序算法详解

排序是计算机科学中的基本操作,Java 提供了多种排序算法来满足不同的需求。常见的排序算法包括冒泡排序、选择排序、插入排序、归并排序、快速排序和堆排序。本文将逐一介绍这些排序算法及其 Java 实现。

1. 冒泡排序 (Bubble Sort)

冒泡排序是一种简单的排序算法,其基本思想是通过重复遍历待排序的元素,比较相邻元素并交换位置,直到所有元素有序。时间复杂度为 O(n^2),适合小规模数据的排序。

1.1 算法步骤

  1. 从头到尾遍历数组。
  2. 比较相邻的元素,如果前一个元素大于后一个元素,则交换它们。
  3. 重复步骤 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. 将选出的最小元素与未排序部分的第一个元素交换。
  3. 将已排序部分的范围扩展,重复步骤 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 算法步骤

  1. 从第二个元素开始,向前与已排序部分比较。
  2. 如果当前元素小于已排序部分的元素,则将已排序部分的元素右移,直到找到合适的位置。
  3. 插入当前元素,扩展已排序部分的范围。

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 算法步骤

  1. 将数组递归地分成两半,直到每个子数组只有一个元素。
  2. 合并已排序的子数组,形成排序好的更大子数组。
  3. 重复步骤 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 算法步骤

  1. 选择一个基准元素。
  2. 将数组分成两部分,一部分小于基准,一部分大于基准。
  3. 递归地对这两部分进行快速排序。

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 算法步骤

  1. 建立一个最大堆(或最小堆)。
  2. 取出堆顶元素,将其与堆的最后一个元素交换,然后调整堆。
  3. 重复步骤 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 排序算法详解

排序是计算机科学中的基本操作&#xff0c;Java 提供了多种排序算法来满足不同的需求。常见的排序算法包括冒泡排序、选择排序、插入排序、归并排序、快速排序和堆排序。本文将逐一介绍这些排序算法及其 Java 实现。 1. 冒泡排序 (Bubble Sort) 冒泡排序是一种简单的排序算法…...

vue3实现拖拽移动位置,拖拽过程中鼠标松开后元素还吸附在鼠标上并随着鼠标移动

发现问题 拖拽元素移动的时候&#xff0c;偶尔会出现拖拽过程中鼠标松开后元素还吸附在鼠标上并随着鼠标移动&#xff0c;要再按一下元素才会被放置下来。但是有时就正常。 问题分析 出现该问题的原因是&#xff1a;这个过程会触发H5原生的拖拽事件&#xff0c;并且不会监听…...

没有屋檐的房子-011

棺材 &#xff08;下&#xff09; 时过境迁这个成语描述了前因后果的两种概念的变化&#xff0c;时间推延和环境的变迁。问题是&#xff0c;时间是什么呢&#xff1f;是环境变化表征了时间的推延&#xff0c;还是时间推延导致了环境的变化&#xff1f;人在多数时候&#xff0c;…...

Puppeteer-Cluster:并行处理网页操作的新利器

在现代Web开发和自动化测试领域&#xff0c;高效地处理多个网页操作任务成为了许多开发者和测试工程师的迫切需求。传统的Puppeteer工具虽然功能强大&#xff0c;但在处理大量并发任务时可能会显得力不从心。为此&#xff0c;Puppeteer-Cluster应运而生&#xff0c;作为一个基于…...

使用Protocol Buffers传输数据

使用 Google Protocol Buffers&#xff08;ProtoBuf&#xff09;与 Kafka 结合来定义和传输数据&#xff0c;可以确保传输数据的结构性、可扩展性和高效性。以下是一个简单的步骤指南&#xff0c;帮助你实现生产者和消费者。 1. 定义 ProtoBuf 消息格式 首先&#xff0c;你需…...

chmod修改文件权限

0 Preface/Foreword 1 chmod使用方法 1.1 修改单个文件 命令如下&#xff1a; sudo chmod xyz fileName xyz: x, y, z分别代表一个8进制数字&#xff08;0-7&#xff09; 1.2 修改文件夹 命令如下&#xff1a; sudo chmod -R xyz folderName...

二叉树--python

二叉树 一、概述 1、介绍 是一种非线性数据结构&#xff0c;将数据一分为二&#xff0c;代表根与叶的派生关系&#xff0c;和链表的结构类似&#xff0c;二叉树的基本单元是结点&#xff0c;每个节点包括值和左右子节点引用。 每个节点都有两个引用&#xff08;类似于双向链…...

matlab数据批量保存为excel,文件名,行和列的名称设置

Excel文件内数据保存结果如下&#xff1a; Excel文件保存结果如下&#xff1a; 代码如下&#xff1a; clear;clc; for jjjj1:10 %这个可以改 jname(jjjj-1)*10; %文件名中变数 这是EXCEL文件名字的一部分 根据自己需要改 jkkkk_num2str(jname); for …...

Pygame中Sprite类实现多帧动画3-2

3.2.3 设置帧的宽度、高度、范围及列数 通过如图6所示的代码设置帧的宽度、高度、范围及列数。 图6 设置帧的宽度、高度、范围及列数的代码 其中&#xff0c;frame_width、frame_height、rect和columns都是MySprite类的属性&#xff0c;在其__init__()方法中定义&#xff0c;…...

C#发送正文带图片带附件的邮件

1&#xff0c;开启服务&#xff0c;获取授权码。以QQ邮箱为例&#xff1a; 点击管理服务&#xff0c;进入账号与安全页面 2&#xff0c;相关设置参数&#xff0c;以QQ邮箱为例&#xff1a; 登录时&#xff0c;请在第三方客户端的密码输入框里面填入授权码进行验证。&#xff0…...

【C#跨平台开发详解】C#跨平台开发技术之.NET Core基础学习及快速入门

1. C#与.NET的发展历程 C#是由Microsoft开发的现代编程语言&#xff0c;最初伴随着.NET Framework发布。随着技术的进步&#xff0c;特别是针对跨平台开发的需求&#xff0c;Microsoft推出了.NET Core&#xff0c;这是一个开源且跨平台的框架&#xff0c;支持Windows、macOS和…...

请解释Java中的死锁产生的原因和解决方法。什么是Java中的并发工具类?请列举几个并解释其用途。

请解释Java中的死锁产生的原因和解决方法。 Java中的死锁是指两个或两个以上的线程在执行过程中&#xff0c;因为争夺资源而造成的一种相互等待的现象&#xff0c;若无外力作用&#xff0c;这些线程都将无法向前推进。死锁是并发编程中常见的问题&#xff0c;它会导致程序运行…...

三分钟带你看懂,低代码开发赋能办公方式转变

随着技术的不断进步&#xff0c;企业对办公效率和灵活性的需求日益增长。低代码开发作为一种新兴的开发模式&#xff0c;正在改变传统的办公方式&#xff0c;让非技术背景的业务人员也能参与到应用的创建和维护中来。本文将带你快速了解低代码开发如何赋能办公方式的转变。 什么…...

视频剪辑软件哪个好用?11款软件轻松上手,让创意视频流畅呈现!

视频剪辑已经涉及到很多个领域&#xff0c;视频剪辑软件的需求也是越来越普遍了。很多朋友在日常办公学习中&#xff0c;经常会遇到视频剪辑的问题。借助专业的视频剪辑软件&#xff0c;我们可以快速的对视频进行剪辑&#xff0c;制作出属于自己的作品。 市面上有各种各样的视频…...

pytest二次开发:生成用例参数

pytest.fixture是一个装饰器&#xff0c;用于声明一个fixture。Fixture是pytest中的一个核心概念&#xff0c;它提供了一种将测试前的准备代码&#xff08;如设置测试环境、准备测试数据等&#xff09;和测试后的清理代码&#xff08;如恢复测试环境、删除临时文件等&#xff0…...

想抹黑华为的 请换一种方式

文&#xff5c;琥珀食酒社 作者 | 积溪 咱能不能有点创意&#xff1f; 能不能换个方式&#xff1f; 之前我说预测过 我说华为的三折叠手机 MateXT非凡大师发布 会引来一大波华为黑 还真是被我说中了 华为MateXT刚曝光 就被黄牛炒到10多万 有人说华为要割韭菜 是电子…...

学习学习学习

​ 1. 面试算法 算法题空间限制64MB 2x 10^7 int codetop.cc 数字中文读 &#x1f517; kmp 奶牛生小牛问题 丑数LCR 168. 丑数 - 力扣&#xff08;LeetCode&#xff09; 166. 分数到小数 - 力扣&#xff08;LeetCode&#xff09; 小数循环节 深入解析力扣166题&#xff…...

requestAnimationFrame原理和使用

requestAnimationFrame 是一个用于在浏览器中实现高效动画的方法。它告诉浏览器你希望执行一个动画&#xff0c;并在下一次重绘之前调用指定的回调函数来更新动画。浏览器会自动优化动画的刷新频率&#xff0c;以确保动画的流畅性和性能。 原理 帧刷新&#xff1a;浏览器通常…...

线程的状态(java)

“苦&#xff1f; 何止是苦~~~~~” 本期内容来分享一下线程状态相关的知识哦&#xff01;&#xff01;&#xff01; 对于进程来说&#xff0c;进程是有两种状态的。 一种是就绪状态&#xff1a;正在CPU上执行&#xff0c;或者随时可以去CPU上执行的。 另一种是阻塞状态&…...

Linux IO模型:IO多路复用

● 应用程序中同时处理多路输入输出流&#xff0c;若采用阻塞模式&#xff0c;得不到预期的目的&#xff1b; ● 若采用非阻塞模式&#xff0c;对多个输入进行轮询&#xff0c;但又太浪费CPU时间&#xff1b; ● 若设置多个进程/线程&#xff0c;分别处理一条数据通路&#xff…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换

目录 关键点 技术实现1 技术实现2 摘要&#xff1a; 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式&#xff08;自动驾驶、人工驾驶、远程驾驶、主动安全&#xff09;&#xff0c;并通过实时消息推送更新车…...

MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释

以Module Federation 插件详为例&#xff0c;Webpack.config.js它可能的配置和含义如下&#xff1a; 前言 Module Federation 的Webpack.config.js核心配置包括&#xff1a; name filename&#xff08;定义应用标识&#xff09; remotes&#xff08;引用远程模块&#xff0…...

规则与人性的天平——由高考迟到事件引发的思考

当那位身着校服的考生在考场关闭1分钟后狂奔而至&#xff0c;他涨红的脸上写满绝望。铁门内秒针划过的弧度&#xff0c;成为改变人生的残酷抛物线。家长声嘶力竭的哀求与考务人员机械的"这是规定"&#xff0c;构成当代中国教育最尖锐的隐喻。 一、刚性规则的必要性 …...

DeepSeek越强,Kimi越慌?

被DeepSeek吊打的Kimi&#xff0c;还有多少人在用&#xff1f; 去年&#xff0c;月之暗面创始人杨植麟别提有多风光了。90后清华学霸&#xff0c;国产大模型六小虎之一&#xff0c;手握十几亿美金的融资。旗下的AI助手Kimi烧钱如流水&#xff0c;单月光是投流就花费2个亿。 疯…...

大模型真的像人一样“思考”和“理解”吗?​

Yann LeCun 新研究的核心探讨&#xff1a;大语言模型&#xff08;LLM&#xff09;的“理解”和“思考”方式与人类认知的根本差异。 核心问题&#xff1a;大模型真的像人一样“思考”和“理解”吗&#xff1f; 人类的思考方式&#xff1a; 你的大脑是个超级整理师。面对海量信…...

【系统架构设计师-2025上半年真题】综合知识-参考答案及部分详解(回忆版)

更多内容请见: 备考系统架构设计师-专栏介绍和目录 文章目录 【第1题】【第2题】【第3题】【第4题】【第5题】【第6题】【第7题】【第8题】【第9题】【第10题】【第11题】【第12题】【第13题】【第14题】【第15题】【第16题】【第17题】【第18题】【第19题】【第20~21题】【第…...

AI书签管理工具开发全记录(十八):书签导入导出

文章目录 AI书签管理工具开发全记录&#xff08;十八&#xff09;&#xff1a;书签导入导出1.前言 &#x1f4dd;2.书签结构分析 &#x1f4d6;3.书签示例 &#x1f4d1;4.书签文件结构定义描述 &#x1f523;4.1. ​整体文档结构​​4.2. ​核心元素类型​​4.3. ​层级关系4.…...

实现p2p的webrtc-srs版本

1. 基本知识 1.1 webrtc 一、WebRTC的本质&#xff1a;实时通信的“网络协议栈”类比 将WebRTC类比为Linux网络协议栈极具洞察力&#xff0c;二者在架构设计和功能定位上高度相似&#xff1a; 分层协议栈架构 Linux网络协议栈&#xff1a;从底层物理层到应用层&#xff08;如…...