探索Java世界中的七大排序算法(上)

news/2024/5/17 11:45:26

文章目录

    • 排序的概念
    • 直接插入排序
    • 希尔排序( 缩小增量排序)
    • 选择排序
    • 堆排序
    • 冒泡排序

在计算机科学中,排序算法是一类重要的算法,它们用于将一组元素按照一定的顺序进行排列。在Java编程中,我们经常需要对数组或集合进行排序操作。本文将介绍Java中七种常见的排序算法,并附带详细的分析过程和代码实现。

排序的概念

排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。

内部排序:数据元素全部放在内存中的排序。
外部排序:数据元素太多不能同时放在内存中,根据排序过程的要求不能在内外存之间移动数据的排序。

直接插入排序

思路

  1. 定义下标 i 和 j 以及临时变量tmp,并把下标 i 的元素存放在tmp中
  2. j 从 i-1 的位置,开始向前遍历,遇到比 tmp大的元素,就把此时 j 下标的元素往后移一位,直到 j 下标小于0停止。
  3. j 下标元素小于tmp,则把tmp元素插入该j下标的下一个位置。

在这里插入图片描述
代码实现

public static void InsertSort(int[] array){for (int i = 1; i < array.length; i++) {int tmp = array[i];int j = i-1;for (; j >=0; j--) {if (array[j] > tmp){array[j+1] = array[j];}else {break;}}array[j+1] = tmp;}}

总结

  1. 元素集合越接近有序,直接插入排序算法的时间效率越高
  2. 时间复杂度:O(N^2)
  3. 空间复杂度:O(1),它是一种稳定的排序算法
  4. 稳定性:稳定

希尔排序( 缩小增量排序)

希尔排序法的基本思想是:先选定一个整数,把待排序文件中所有记录分成多个组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组和排序的工作。当到达=1时,所有记录在统一组内排好序。

思路:

  1. 定义gap = 数组长度\2。
  2. 把待排序列分为gap个组,每个组的第一个元素和最后一个元素进行比较交换。
  3. 重复上述操作
  4. 当gap为1时,进行插入排序。
    在这里插入图片描述

在这里插入图片描述
代码实现

public static void shellSort(int[] array) {int gap = array.length;//nwhile (gap > 1) {gap = gap/3 + 1;shell(array,gap);}}private static void shell(int[] array,int gap) {//i++ 交替进行插入排序for (int i = gap; i < array.length; i++) {int tmp = array[i];int j = i-gap;for (; j >= 0 ; j -= gap) {if(array[j] > tmp) {array[j+gap] = array[j];}else {break;}}array[j+gap] = tmp;}}

时间复杂度: O(N^1.3);

空间复杂度: O(1);

稳定性: 不稳定。

希尔排序的特性总结:

  1. 希尔排序是对直接插入排序的优化。
  2. 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了
  3. 希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在好些树中给出的希尔排序的时间复杂度都不固定。

选择排序

思路: 每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 。
在这里插入图片描述
实现

  1. 定义 i 和 j 以及临时下标minIndex,minIndex记录 i 的下标。
  2. j 从 i 下一个位置开始往后遍历,遇到小于array[minIndex]时更新min,min指向每次遍历的最小值下标,直到遍历完一次数组。
  3. 一次遍历完后array[i]和minIndex下标进行交换。

代码实现

private static void swap(int[] array,int i,int j) {int tmp = array[i];array[i] = array[j];array[j] = tmp;}public static void selectSort1(int[] array) {for (int i = 0; i < array.length; i++) {int minIndex = i;for (int j = i+1; j < array.length; j++) {if(array[j] < array[minIndex]) {minIndex = j;}}swap(array,minIndex,i);}}

总结:
时间复杂度: O(N^2);
空间复杂度: O(1);
稳定性: 不稳定;

堆排序

注意:排升序需要建大根堆,排降序建小根堆。此文章默认举例排升序

思路:

  1. 首先得建立一个大根堆。
  2. 把根节点与最后一个节点交换,每一次交换,最后一个节点向前走一步。
  3. 进行堆向下调整。

在这里插入图片描述
代码实现:

private static void createBigHeap(int[] array) {for (int parent = (array.length-1-1) / 2; parent >= 0; parent--) {siftDown(parent,array,array.length);}}private static void siftDown(int parent,int[] array,int end) {int child = 2*parent+1;while (child < end) {if(child + 1 < end && array[child] < array[child+1]) {child++;}//child下标 就是左右孩子最大值的下标if(array[child] > array[parent]) {swap(array,child,parent);parent = child;child = 2*parent+1;}else {break;}}}public static void heapSort(int[] array) {createBigHeap(array);int end = array.length-1;while (end >= 0) {swap(array,0,end);siftDown(0,array,end);end--;}}

冒泡排序

思想:所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。

  1. 定义i遍历数组,控制趟数,总体趟数比数组长度少1;
  2. 每趟让一个较大值移动到尾部。
  3. 定义j每次从0下标进行两两比较交换。
public static void bubbleSort(int[] array) {for (int i = 0; i < array.length-1; i++) {boolean flg = false;for (int j = 0; j < array.length-1-i; j++) {if(array[j] > array[j+1]) {swap(array,j,j+1);flg = true;}}if(!flg) {break;}}

总结

  1. 冒泡排序是一种非常容易理解的排序
  2. 时间复杂度:O(N^2)
  3. 空间复杂度:O(1)
  4. 稳定性:稳定

本文介绍了Java中七大常见的排序算法,包括冒泡排序、选择排序、插入排序、希尔排序和堆排序。每种排序算法的原理、实现方法和代码实现都有详细的解释和示例。通过学习和理解这些排序算法,我们可以更好地应用它们来解决实际问题,并提高程序的效率和性能。


http://www.mrgr.cn/p/18236811

相关文章

高并发(AQS)

AQS 抽象的队列同步器框架,主要通过程序来构建锁和同步器AQS 抽象的队列同步器框架,主要通过程序来构建锁和同步器 AQS 的全称为 AbstractQueuedSynchronizer ,翻译过来的意思就是抽象队列同步器,它和Java的Synchronized作用和一样,用来同步加锁; 特性对比ReentrantLock …

JAVA基础-流程控制、字符串

一、java基础 1、java主类结构 package com.study.again001; 包名public class helloword { 类名 static String s1 = "1"; 静态成员变量 public static void main(String[] args) { main方法 String s2 = "2"; 局部变量 …

C到二进制概述

此帖是记录视频内容,防止后续自己遗忘 一、预处理 1、库文件 预处理等于一个文本粘贴过程,编译后把库文件展开,展开本质也为粘贴内容include 本质是在其中特定路径搜索(usr/include...),而#include "xxx"是在当前路径下进行搜索 。其中#include" "高于…

Qt6连接MySQL

Qt6连接MySQL Qt6编译MySQL的过程太变态了&#xff0c;MinGW和MSVC都很费劲。 主要参考qt6.5.0MySQL驱动手动编译以及数据库连接详细教程以及注意事项附资源链接&#xff0c;这篇文章堪称保姆级教程&#xff0c;写的十分详细。 笔者这里踩了个坑&#xff0c;在按照上文中的过…

AliyunCTF 2024 - BadApple

文章目录 前言环境搭建漏洞分析漏洞利用参考 前言 本文首发于看雪论坛 https://bbs.kanxue.com/thread-281291.htm 依稀记得那晚被阿里CTF支配的恐惧&#xff0c;今年的阿里CTF笔者就做了一道签到PWN题&#xff0c;当时也是下定决心要学习 jsc pwn 然后复现这道 BadApple 题目…

UI——数据表和UI绑定

目的创建数据表 创建UI控件 玩家角色蓝图UI按键逻辑 UI与数据表绑定1.创建数据表2.创建UI控件3.玩家角色蓝图UI按键逻辑4.UI与数据表绑定本文来自博客园,作者:荒坂株式会社,博客内容均属学习笔记,只做交流之用

MBR20200FCT-ASEMI肖特基二极管MBR20200FCT

MBR20200FCT-ASEMI肖特基二极管MBR20200FCT编辑:ll MBR20200FCT-ASEMI肖特基二极管MBR20200FCT 型号:MBR20200FCT 品牌:ASEMI 封装:TO-220 最大平均正向电流(IF):20A 最大循环峰值反向电压(VRRM):200V 最大正向电压(VF):0.90V 工作温度:-65C~175C 反向恢复时间:…

ELK-Kibana 部署

目录 一、在 node1 节点上操作 1.1.安装 Kibana 1.2.设置 Kibana 的主配置文件 1.3.启动 Kibana 服务 1.4.验证 Kibana 1.5.将 Apache 服务器的日志&#xff08;访问的、错误的&#xff09;添加到 ES 并通过 Kibana 显示 1.6. 浏览器访问 二、部署FilebeatELK&…

App测试中,强制等待和隐式等待谁更强?

简介 添加等待是为了确保自动化脚本在执行过程中与应用程序之间的同步和稳定性。 应用程序的响应时间是不确定的,可能存在网络延迟、加载时间、动画效果等因素。如果在执行自动化脚本时没有适当的等待机制,脚本可能会在应用程序还未完成相应操作或加载完成之前继续执行下一步…

Spring AOP的实现方式与原理

目录 认识IOC与AOP AOP的实现方式 Aspect注解实现AOP 自定义注解实现AOP Spring AOP原理 代理模式 静态代理和动态代理 JDK动态代理 CGLIB动态代理 Spring AOP实现的哪种代理 认识IOC与AOP IOC又称为控制反转,也就是控制权发生了反转.在传统的程序中,我们是需要自己…

设计模式——迭代器模式15

迭代器模式提供一种方法访问一个容器对象中各个元素&#xff0c;而又不需暴露该对象的内部细节。 设计模式&#xff0c;一定要敲代码理解 抽象迭代器 /*** 迭代抽象* */ public interface Iterator<A> {A next();boolean hasNext(); }迭代器实现 /*** author ggbond*…

数据加密技术在数据安全中的作用

随着信息技术的飞速发展,数据已成为现代社会最宝贵的资产之一。然而,数据的快速增长也带来了安全风险,包括数据泄露、篡改和滥用等。数据加密技术作为保护数据安全的重要手段,其重要性日益凸显。PrimiHub一款由密码学专家团队打造的开源隐私计算平台,专注于分享数据安全、…

生态短讯 | Tapdata 与 TDengine 完成产品兼容性互认证,打造物联网实时数据生态

近日,深圳钛铂数据有限公司自主研发的钛铂实时数据平台与 TDengine完成相互兼容性测试,兼容性良好,系统功能正常,运行稳定。近月,深圳钛铂数据有限公司(以下简称钛铂数据)自主研发的实时数据平台(Tapdata Live Data Platform)与北京涛思数据科技有限公司(以下简称涛思…

YOLTV8 — 大尺度图像目标检测框架(欢迎star)

YOLTV8 — 大尺度图像目标检测框架【ABCnutter/YOLTV8: &#x1f680;】 针对大尺度图像&#xff08;如遥感影像、大尺度工业检测图像等&#xff09;&#xff0c;由于设备的限制&#xff0c;无法利用图像直接进行模型训练。将图像裁剪至小尺度进行训练&#xff0c;再将训练结果…

Qt 6.5.5 链接和QML与C++交互的若干问题

需求描述 Qt Quick开发桌面组件,使用讯飞API(提供头文件、静态库、动态库),希望部署到Windows平台,在Qt Creator开发。 QML与C++交互 主要参考:QML与CPP,https://blog.csdn.net/gongjianbo1992/article/details/87965925 另有参考:信号与槽,https://blog.csdn.net/ife…

VK3602K SOP8抗干扰2键/2路/2按键/2通道触摸感应芯片,应用于加湿器触摸IC等大小家电产品

产品品牌:永嘉微电/VINKA 产品型号:VK3602K 封装形式:SOP8 概述 VK3602K具有2个触摸按键,可用来检测外部触摸按键上人手的触摸动作。该芯片具有较高的集成度,仅需极少的外部组件便可实现触摸按键的检测。 提供了2路直接输出功能,可通过IO脚选择输出电平。芯片内部采用特殊…

【运维自动化-配置平台】如何创建业务及拓扑(集群-模块)

业务&#xff0c;是蓝鲸 CD 体系中比较重要的概念和维度&#xff0c;日常使用中主机、进程、业务拓扑的管理都需要依赖已经存在的业务&#xff0c;其他蓝鲸体系产品也基本上都是围绕业务的维度来提供对应的服务和相关的鉴权。1、创建业务/业务集 请确保有创建业务的权限&#…

BGE M3-Embedding 模型介绍

BGE M3-Embedding是BAAI开源的embedding模型,支持多语言,多粒度,多功能检索,本文介绍模型的相关信息BGE M3-Embedding来自BAAI和中国科学技术大学,是BAAI开源的模型。相关论文在https://arxiv.org/abs/2402.03216,论文提出了一种新的embedding模型,称为M3-Embedding,它…

redis自学(37)集群伸缩

集群伸缩 添加一个节点到集群: Redis-cli--cluster提供了很多操作集群的命令,可以通过下面方式查看:比如,添加节点的命令先输入新增的ip和端口号,后输入集群已经有的ip和端口号好指定添加到哪个集群。默认是增加master节点,加上--cluster-slave是变成了slave。--cluster-…

LLM-大模型演化分支树、GPT派发展阶段及训练流程图、Infini-Transformer说明

大模型是怎么演进的&#xff1f; Encoder Only: 对应粉色分支&#xff0c;即BERT派&#xff0c;典型模型&#xff1a; BERT 自编码模型&#xff08;Autoencoder Model&#xff09;&#xff1a;通过重建句子来进行预训练&#xff0c;通常用于理解任务&#xff0c;如文本分类和阅…