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

常见八大排序算法

今天我们带来数据结构中常见的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汽车&#xff0c;搭载EA211发动机和手自一体变速器&#xff0c;累计行驶里程约为4.5万km。该车行驶中挡位偶尔会锁在D3挡&#xff0c;车速最高约50 km/h&#xff0c;且组合仪表上的发动机故障灯和EPC灯异常点亮。 故障诊断  用故障检测仪检…...

Linux之HugePage的原理与使用

Linux之HugePage的原理与使用 虚拟地址与物理地址虚拟地址物理地址虚拟地址与物理地址的转换 HugePage的概念Linux使用HugePage创建HugePage在程序中使用HugePage 总结 虚拟地址与物理地址 在研究HugePage之前&#xff0c;首先需要明白虚拟地址和物理地址的概念。在计算机系统…...

一步步优化Redis实现分布式锁

分布式锁概念 在多线程的程序里&#xff0c;为了避免同时操作一个共享变量产生数据问题&#xff0c;会加一个互斥锁&#xff0c;以确保共享变量的正确性&#xff0c;使用范围是同一个进程。 那如果是多个进程&#xff0c;需要同时操作一个共享资源&#xff0c;如何互斥呢&…...

C++进阶——二叉搜索树

目录 一、基本概念 二、性能分析 三、模拟实现 四、使用场景 1.key搜索场景 2.key/value搜索场景 一、基本概念 二叉搜索树&#xff08;Binary Search Tree&#xff09;&#xff0c;看名字就知道,是可以用来搜索数据的一种二叉树。 它可以是空树&#xff08;一个数据都…...

Require:业界优秀的HTTP管理方案。

方案异步JDK额外依赖特点HttpURLConnection 【优点】Java内置&#xff0c;简单易用。对于简单的HTTP请求和响应处理非常合适。 【缺点】功能相对较少&#xff0c;不支持现代特性&#xff08;如异步请求、连接池等&#xff09;。API相对繁琐&#xff0c;处理复杂请求时代码冗长。…...

装饰模式(Decorator Pattern)在 Go 语言中的应用

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

Windows系统部署redis自启动服务

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

34岁IT男的职场十字路口:是失业预警,还是转型契机?

在信息技术这片充满机遇与挑战的广袤领域&#xff0c;34岁&#xff0c;一个看似正值壮年却暗藏危机的年龄&#xff0c;成为了许多IT男性不得不面对的职场考验。当“34岁现象”逐渐凸显&#xff0c;我们不禁要问&#xff1a;在这个快速变化的时代&#xff0c;34岁的IT男&#xf…...

复试经验分享《三、计算机学科专业基础综合》- 数据结构篇

复试经验分享 三、计算机学科专业基础综合 3.1 数据结构 3.1.1 概念 时间复杂度 时间复杂度是指执行算法所需要的计算工作量一般情况下&#xff0c;按照基本操作次数最多的输入来计算时间复杂度&#xff0c;并且多数情况下我们去最深层循环内的语句所描述的操作作为基本操作…...

数学建模算法与应用 第16章 优化与模拟方法

目录 16.1 线性规划 Matlab代码示例&#xff1a;线性规划求解 16.2 整数规划 Matlab代码示例&#xff1a;整数规划求解 16.3 非线性规划 Matlab代码示例&#xff1a;非线性规划求解 16.4 蒙特卡洛模拟 Matlab代码示例&#xff1a;蒙特卡洛模拟计算圆周率 习题 16 总结…...

windows下安装、配置neo4j并服务化启动

第一步&#xff1a;下载Neo4j压缩包 官网下载地址&#xff1a;https://neo4j.com/download-center/ &#xff08;官网下载真的非常慢&#xff0c;而且会自己中断&#xff0c;建议从以下链接下载&#xff09; 百度网盘下载地址&#xff1a;链接&#xff1a;https://pan.baid…...

【JVM】—深入理解G1回收器—回收过程详解

深入理解G1回收器—回收过程详解 ⭐⭐⭐⭐⭐⭐ Github主页&#x1f449;https://github.com/A-BigTree 笔记链接&#x1f449;https://github.com/A-BigTree/Code_Learning ⭐⭐⭐⭐⭐⭐ 如果可以&#xff0c;麻烦各位看官顺手点个star~&#x1f60a; 文章目录 深入理解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) 前言 接下来我们会使用的数据表如下&#xff1a; 对应的实体类为&#xff1a;UserInfo 所有的准备工作都在如下文章。 MyBatis 操作…...

智汇云舟亮相WAFI世界农业科技创新大会,并参编数字农业产业图谱

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

昇思MindSpore进阶教程--数据处理性能优化(中)

大家好&#xff0c;我是刘明&#xff0c;明志科技创始人&#xff0c;华为昇思MindSpore布道师。 技术上主攻前端开发、鸿蒙开发和AI算法研究。 努力为大家带来持续的技术分享&#xff0c;如果你也喜欢我的文章&#xff0c;就点个关注吧 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语言实现)

一、图的概念 顶点&#xff08;Vertex&#xff09;&#xff1a;图中的数据元素&#xff0c;我们称之为顶点&#xff0c;图至少有一个顶点&#xff08;非空有穷集合&#xff09;。 边&#xff08;Edge&#xff09;&#xff1a;顶点之间的关系用边表示。 1.图&#xff08;Graph…...

GPT 生成绘画_Java语言例子_超详细

基于spring ai &#xff1a;简化Java AI开发&#xff0c;提升效率与维护性 过去在使用Java编写AI应用时&#xff0c;主要困境在于缺乏统一的标准化封装&#xff0c;开发者需要针对不同的AI服务提供商查阅各自独立的文档并进行接口对接&#xff0c;这不仅增加了开发的工作量&am…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

Bean 作用域有哪些?如何答出技术深度?

导语&#xff1a; Spring 面试绕不开 Bean 的作用域问题&#xff0c;这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开&#xff0c;结合典型面试题及实战场景&#xff0c;帮你厘清重点&#xff0c;打破模板式回答&#xff0c…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…...