常见八大排序算法
今天我们带来数据结构中常见的8大排序算法。
排序算法 | 平均时间复杂度 | 最好情况 | 最坏情况 | 空间复杂度 | 稳定性 |
冒泡排序 | O(n方) | O(n方) | O(n方) | O(1) | 稳定 |
插入排序 | O(n方) | O(n方) | O(n方) | O(1) | 稳定 |
选择排序 | O(n方) | O(n方) | O(n方) | O(1) | 不稳定 |
希尔排序 | O(n1.3方到1,5方) | O(n) | O(n方) | O(1) | 不稳定 |
堆排序 | O(n log n) | O(n log n) | O(n log n) | O(1) | 不稳定 |
快速排序 | O(n log n) | O(n log n) | O(n方) | O(n log n) | 不稳定 |
归并排序 | O(n log n) | O(n log n) | O(n log n) | O(n) | 稳定 |
计数排序 | O(n + k) | O(n + k) | O(n + k) | O(k) | 不稳定 |
一,冒泡排序
思路:1,从头到尾比较相邻的元素,2,重复第一步n-1次
代码实现:
public void BubbleSort(int[] array){int[] str = Arrays.copyOf(array,array.length);for (int i = 0; i < str.length; i++) {for (int j = 0; j < str.length-1-i; j++) {if(str[j]<str[j+1]){swap(str,j,j+1);}}}System.out.println(Arrays.toString(str));}
swap是交换,
private void swap(int[] str,int i,int j){int tmp = str[i];str[i] = str[j];str[j] = tmp;}
代码优化: 优化也不会优化到多好基本还是O(n方的复杂度)
public void BubbleSortLevel(int[] array){int[] str = Arrays.copyOf(array,array.length);for (int i = 0; i < str.length; i++) {boolean a = false;for (int j = 0; j < str.length-1-i; j++) {if(str[j]<str[j+1]){swap(str,j,j+1);a = true;}}if(!a){break;}}System.out.println(Arrays.toString(str));}
二,插入排序
思路; 1,定义两个下标i,j,tmp,i从1开始向后遍历,把初始的下标值赋给tmp 2,j每次从i前面开始向前遍历,比较j下标的元素和tmp的值。
代码实现:
public void InsertSort(int[] array){int[] str = Arrays.copyOf(array,array.length);int j=0;int tmp=0;for (int i = 1; i < str.length; i++) {tmp = str[i];for (j = i-1; j >=0 ; j--) {if(str[j]<tmp){str[j+1] = str[j];}else {break;}}str[j+1] = tmp;}System.out.println(Arrays.toString(str));}
三,选择排序
思路: 1,定义两个下标i,j;i从左向右遍历:2,我们创建一个tmpIndex记录i下标的值,j每次都在i的左边,与tmpIndex的值进行比较,记录新的tmpIndex的值,与i下标交换,重复这个步骤。
代码实现:
public void ChooseSort(int[] array){int[] str = Arrays.copyOf(array,array.length);int j= 0;int tmpIndex = 0;for (int i = 0; i < str.length; i++) {tmpIndex = i;for (j = i+1; j < str.length; j++) {if(str[j]<str[tmpIndex]){tmpIndex = j;}}swap(str,i,tmpIndex);}System.out.println(Arrays.toString(str));}
四,希尔排序
思路: 希尔排序实际就是多次进行快速排序,但是我们每次是不同的几组数进行排序,我们初始一个gap,gap的取值不一,我们一数组长度/2来赋给gap,每次相邻为gap的元素进行插入排序,再对gap/2,直到gap为1,我们的思路是插入排序对越有序的数组排序越有序
代码实现:
public void ShellSort(int[] array){int[] str = Arrays.copyOf(array,array.length);int gap = str.length/2;while (gap>=1){ShellSort__InsertSort(str,gap);gap/=2;}System.out.println(Arrays.toString(str));}private void ShellSort__InsertSort(int[] str,int gap){int tmp = 0;int j = 0;for (int i = gap; i < str.length; i++) {tmp = str[i];for (j = i-gap; j >= 0; j-=gap) {if(str[j]<tmp){str[j+gap] =str[j];}else {break;}}str[j+gap] = tmp;}}
五,堆排序
思路: 以升序为例,降序建小根堆,升序建大根堆,
1,建堆 2,栈顶元素与尾元素互换,再进行向下调整 3,直到重复步骤2直到0下标。
代码实现:
public void HeapSort(int[] array){int[] str = Arrays.copyOf(array,array.length);CreateHeap(str);for (int i = str.length-1; i >=0 ; i--) {swap(str,i,0);ShiftDown(str,0,i);}System.out.println(Arrays.toString(str));}private void CreateHeap(int[] str){int c = str.length-1;int p = (c-1)/2;while (p>=0){ShiftDown(str,p,str.length);p--;}System.out.println(Arrays.toString(str));}private void ShiftDown(int[] str, int parent,int usdSize){int child = 2*parent+1;while (child<usdSize){if(child+1<usdSize && str[child]<str[child+1]){child++;}if(str[child]>str[parent]){swap(str,child,parent);parent = child;child = 2*parent+1;}else {break;}}}
六,快速排序
思路: 1,选择一个基准,定义两个下标,一个从右往左走(先走),一个从左往右走,右边遇到小于基准的与左边大于基准的交换,
2,找到基准,从基准左边和右边递归,重复1的过程。
代码实现(递归实现):
public void QuickSort(int[] array){int[] str = Arrays.copyOf(array,array.length);QuickSortChild(str,0,str.length-1);System.out.println(Arrays.toString(str));}private void QuickSortChild(int[] str,int start,int end){if(start>end){return;}int left = start;int right = end;int part = partition(str,left,right);QuickSortChild(str,start,part-1);QuickSortChild(str,part+1,end);}private int partition(int[] str,int start,int end){int left = start;int right = end;int cmp = str[left];while (left<right){while (left<right && str[right]<=cmp){right--;}while (left<right && str[left]>=cmp){left++;}if(left<right){swap(str,left,right);}}swap(str,start,left);return left;}
代码优化(递归实现):(三数取中法)
public void QuickSort2(int[] array){int[] str = Arrays.copyOf(array,array.length);QuickSortChild(str,0,str.length-1);System.out.println(Arrays.toString(str));}private void QuickSortChild2(int[] str,int start,int end){if(start>end){return;}int left = start;int right = end;int mid = middle(left,(left+right)/2,right);swap(str,start,mid);int part = partition(str,left,right);QuickSortChild(str,start,part-1);QuickSortChild(str,part+1,end);}private int partition2(int[] str,int start,int end){int left = start;int right = end;int cmp = str[left];while (left<right){while (left<right && str[right]<=cmp){right--;}while (left<right && str[left]>=cmp){left++;}if(left<right){swap(str,left,right);}}swap(str,start,left);return left;}private int middle(int left,int middle,int right){int[] arr = new int[]{left,middle,right};Arrays.sort(arr);return arr[1];}
代码实现(非递归实现):
public void QuickSort3(int[] array){int[] str = Arrays.copyOf(array,array.length);QuickSortChild3(str,0,array.length-1);System.out.println(Arrays.toString(str));}private void QuickSortChild3(int[] str,int start,int end){Deque<Integer> stack = new ArrayDeque<>();int part = partition3(str,start,end);if (part+1<end){stack.push(end);stack.push(part+1);}if(part-1>start){stack.push(part-1);stack.push(start);}while (!stack.isEmpty()){end = stack.pop();start = stack.pop();part = partition3(str,start,end);if (part+1<end){stack.push(end);stack.push(part+1);}if(part-1>start){stack.push(part-1);stack.push(start);}}}private int partition3(int[] str,int start,int end){int left = start;int right = end;int cmp = str[left];while (left<right){while (left<right && str[right]<=cmp){right--;}while (left<right && str[left]>=cmp){left++;}if(left<right){swap(str,left,right);}}swap(str,start,left);return left;}
七,归并排序
思路: 1,我们把数据平均分为两个部分定义左中右三个下标,左边递归,右边递归,
2,当左下标大于等于右递下标归停止,我们使用合并数组的方法,把每层递归后有序的左右子树有序化
代码实现:
public void MergeSort(int[] array){int[] str = Arrays.copyOf(array,array.length);MergeSortChild(str,0,str.length-1);System.out.println(Arrays.toString(str));}private void MergeSortChild(int[] str,int left, int right){if(left>=right){return;}int mid = (left+right)/2;MergeSortChild(str,left,mid);MergeSortChild(str,mid+1,right);MergeSort__new(str,left,mid,right);}private void MergeSort__new(int[] str,int left,int mid,int right){int s1 = left;int e1 = mid;int s2 = mid+1;int e2 = right;int[] arr = new int[right-left+1];int i=0;while (s1<=e1 && s2<=e2){if(str[s1]<=str[s2]){arr[i] = str[s1];i++;s1++;}if(str[s2]<str[s1]){arr[i] = str[s2];i++;s2++;}}while (s1<=e1){arr[i] = str[s1];i++;s1++;}while (s2<=e2){arr[i] = str[s2];i++;s2++;}for (int k = 0; k < i; k++) {str[k+left] = arr[k];}}
八,计数排序
计数排序适合排那些一定范围的大量数据,比如1-100的考试成绩
思路: 1,我们遍历原数组,找出最大值最小值,用他们的差值大小构建一个计数数组,
2,把原数组出现的数字-min放到计数数组里,有一个计数数组就加一,循环遍历计数数组,直到计数数组全部元素都为0
代码实现:
public void CountIngSort(int[] array){int[] str = Arrays.copyOf(array,array.length);int max = str[0];int min = str[0];for (int i = 0; i <str.length ; i++) {if(str[i]>max){max = str[i];}if(str[i]<min){min = str[i];}}int[] count = new int[max-min+1];for (int i = 0; i < str.length; i++) {int a = str[i];count[a-min]+=1;}int j = 0;int i = 0;while (i<count.length) {while (count[i]!=0){str[j] = i+min;j++;count[i]--;}i++;}System.out.println(Arrays.toString(str));}
相关文章:

常见八大排序算法
今天我们带来数据结构中常见的8大排序算法。 排序算法平均时间复杂度最好情况最坏情况空间复杂度稳定性冒泡排序O(n方)O(n方)O(n方)O(1)稳定插入排序O(n方)O(n方)O(n方)O(1)稳定选择排序O(n方)O(n方)O(n方)O(1)不稳定希尔排序O(n1.3方到1,5方)O(n)O(n方)O(1)不稳定堆排序O(n lo…...

汽车免拆诊断案例 | 2022款大众捷达VS5车行驶中挡位偶尔会锁在D3挡
故障现象 一辆2022款大众捷达VS5汽车,搭载EA211发动机和手自一体变速器,累计行驶里程约为4.5万km。该车行驶中挡位偶尔会锁在D3挡,车速最高约50 km/h,且组合仪表上的发动机故障灯和EPC灯异常点亮。 故障诊断 用故障检测仪检…...

Linux之HugePage的原理与使用
Linux之HugePage的原理与使用 虚拟地址与物理地址虚拟地址物理地址虚拟地址与物理地址的转换 HugePage的概念Linux使用HugePage创建HugePage在程序中使用HugePage 总结 虚拟地址与物理地址 在研究HugePage之前,首先需要明白虚拟地址和物理地址的概念。在计算机系统…...
一步步优化Redis实现分布式锁
分布式锁概念 在多线程的程序里,为了避免同时操作一个共享变量产生数据问题,会加一个互斥锁,以确保共享变量的正确性,使用范围是同一个进程。 那如果是多个进程,需要同时操作一个共享资源,如何互斥呢&…...

C++进阶——二叉搜索树
目录 一、基本概念 二、性能分析 三、模拟实现 四、使用场景 1.key搜索场景 2.key/value搜索场景 一、基本概念 二叉搜索树(Binary Search Tree),看名字就知道,是可以用来搜索数据的一种二叉树。 它可以是空树(一个数据都…...
Require:业界优秀的HTTP管理方案。
方案异步JDK额外依赖特点HttpURLConnection 【优点】Java内置,简单易用。对于简单的HTTP请求和响应处理非常合适。 【缺点】功能相对较少,不支持现代特性(如异步请求、连接池等)。API相对繁琐,处理复杂请求时代码冗长。…...

装饰模式(Decorator Pattern)在 Go 语言中的应用
文章目录 引言什么是装饰模式?在Go语言中的应用定义接口实现具体逻辑创建装饰器使用装饰器 装饰模式 vs 中间件装饰模式中间件区别 总结 引言 在软件开发中,设计模式是解决常见问题的模板。装饰模式(Decorator Pattern)是一种结构…...

Windows系统部署redis自启动服务
文章目录 引言I redis以本地服务运行(Windows service)使用MSI安装包配置文件,配置端口和密码II redis服务以终端命令启动缺点运行redis-server并指定端口和密码III 知识扩展确认redis-server可用性Installing the Service引言 服务器是Windows系统,所以使用Windows不是re…...

34岁IT男的职场十字路口:是失业预警,还是转型契机?
在信息技术这片充满机遇与挑战的广袤领域,34岁,一个看似正值壮年却暗藏危机的年龄,成为了许多IT男性不得不面对的职场考验。当“34岁现象”逐渐凸显,我们不禁要问:在这个快速变化的时代,34岁的IT男…...
复试经验分享《三、计算机学科专业基础综合》- 数据结构篇
复试经验分享 三、计算机学科专业基础综合 3.1 数据结构 3.1.1 概念 时间复杂度 时间复杂度是指执行算法所需要的计算工作量一般情况下,按照基本操作次数最多的输入来计算时间复杂度,并且多数情况下我们去最深层循环内的语句所描述的操作作为基本操作…...

数学建模算法与应用 第16章 优化与模拟方法
目录 16.1 线性规划 Matlab代码示例:线性规划求解 16.2 整数规划 Matlab代码示例:整数规划求解 16.3 非线性规划 Matlab代码示例:非线性规划求解 16.4 蒙特卡洛模拟 Matlab代码示例:蒙特卡洛模拟计算圆周率 习题 16 总结…...

windows下安装、配置neo4j并服务化启动
第一步:下载Neo4j压缩包 官网下载地址:https://neo4j.com/download-center/ (官网下载真的非常慢,而且会自己中断,建议从以下链接下载) 百度网盘下载地址:链接:https://pan.baid…...

【JVM】—深入理解G1回收器—回收过程详解
深入理解G1回收器—回收过程详解 ⭐⭐⭐⭐⭐⭐ Github主页👉https://github.com/A-BigTree 笔记链接👉https://github.com/A-BigTree/Code_Learning ⭐⭐⭐⭐⭐⭐ 如果可以,麻烦各位看官顺手点个star~😊 文章目录 深入理解G1回收…...

2、CSS笔记
文章目录 二、CSS基础CSS简介CSS语法规范CSS代码风格CSS选择器CSS基础选择器标签选择器类选择器--最常用id选择器通配符选择器 CSS复合选择器交集选择器--重要并集选择器--重要后代选择器--最常用子代选择器--重要兄弟选择器相邻兄弟选择器通用兄弟选择器 属性选择器伪类选择器…...

使用XML实现MyBatis的基础操作
目录 前言 1.准备工作 1.1⽂件配置 1.2添加 mapper 接⼝ 2.增删改查操作 2.1增(Insert) 2.2删(Delete) 2.3改(Update) 2.4查(Select) 前言 接下来我们会使用的数据表如下: 对应的实体类为:UserInfo 所有的准备工作都在如下文章。 MyBatis 操作…...

智汇云舟亮相WAFI世界农业科技创新大会,并参编数字农业产业图谱
10月10日,2024WAFI世界农业科技创新大会农食行业创新与投资峰会在北京金海湖国际会展中心举行。中国农业大学MBA教育中心主任、教授付文阁、平谷区委常委、统战部部长刘堃、华为公共事业军团数字政府首席专家刘丹、荷兰瓦赫宁根大学前校长Aalt Dijkhuizen、牧原食品…...

昇思MindSpore进阶教程--数据处理性能优化(中)
大家好,我是刘明,明志科技创始人,华为昇思MindSpore布道师。 技术上主攻前端开发、鸿蒙开发和AI算法研究。 努力为大家带来持续的技术分享,如果你也喜欢我的文章,就点个关注吧 shuffle性能优化 shuffle操作主要是对有…...

Vivado - Aurora 8B/10B IP
目录 1. 简介 2. 设计调试 2.1 Physical Layer 2.2 Link Layer 2.3 Receiver 2.4 IP 接口 2.5 调试过程 2.5.1 Block Design 2.5.2 释放 gt_reset 2.5.3 观察数据 3. 实用技巧 3.1 GT 坐标与布局 3.1.1 选择器件并进行RTL分析 3.1.2 进入平面设计 3.1.3 收发器布…...

图(Java语言实现)
一、图的概念 顶点(Vertex):图中的数据元素,我们称之为顶点,图至少有一个顶点(非空有穷集合)。 边(Edge):顶点之间的关系用边表示。 1.图(Graph…...

GPT 生成绘画_Java语言例子_超详细
基于spring ai :简化Java AI开发,提升效率与维护性 过去在使用Java编写AI应用时,主要困境在于缺乏统一的标准化封装,开发者需要针对不同的AI服务提供商查阅各自独立的文档并进行接口对接,这不仅增加了开发的工作量&am…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...

vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...

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

mac:大模型系列测试
0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何,是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试,是可以跑通文章里面的代码。训练速度也是很快的。 注意…...
【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统
Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...
鸿蒙HarmonyOS 5军旗小游戏实现指南
1. 项目概述 本军旗小游戏基于鸿蒙HarmonyOS 5开发,采用DevEco Studio实现,包含完整的游戏逻辑和UI界面。 2. 项目结构 /src/main/java/com/example/militarychess/├── MainAbilitySlice.java // 主界面├── GameView.java // 游戏核…...

Java设计模式:责任链模式
一、什么是责任链模式? 责任链模式(Chain of Responsibility Pattern) 是一种 行为型设计模式,它通过将请求沿着一条处理链传递,直到某个对象处理它为止。这种模式的核心思想是 解耦请求的发送者和接收者,…...

LeetCode - 148. 排序链表
目录 题目 思路 基本情况检查 复杂度分析 执行示例 读者可能出的错误 正确的写法 题目 148. 排序链表 - 力扣(LeetCode) 思路 链表归并排序采用"分治"的策略,主要分为三个步骤: 分割:将链表从中间…...