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时间; ● 若设置多个进程/线程,分别处理一条数据通路ÿ…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...