当前位置: 首页 > 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…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...

如何更改默认 Crontab 编辑器 ?

在 Linux 领域中&#xff0c;crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用&#xff0c;用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益&#xff0c;允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...

FFmpeg:Windows系统小白安装及其使用

一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】&#xff0c;注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录&#xff08;即exe所在文件夹&#xff09;加入系统变量…...