基本排序算法
目录
一,插入排序
二,希尔排序
三,选择排序
四,冒泡排序
五,快排
5.1 Hoare法
5.2 挖坑法
5.3 指针法
5.4 非递归写法
六,归并排序
6.1 递归
6.2 非递归
一,插入排序
基本思想:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列。

/*** 直接插入排序* 时间复杂度:O(n^2)* 空间复杂度:O(1)* 稳定性:稳定*/public void insertSort(int[] arr){for (int i = 1; i < arr.length; i++) {int tmp = arr[i];//要插入的元素int j = i-1;for (; j >= 0; j--) {if(arr[j] > tmp){//判断是否插入arr[j+1] = arr[j];}else{break;}}arr[j+1] = tmp;}}
二,希尔排序
基本思想:先选定一个整数,把待排序文件中所有记录分成多个组,所有距离为gap的记录分在同一组内,并对每一组内的记录进行排序。然后gap/=2,重复上述分组和排序的工作。当到达gap=1时,所有记录在统一组内排好序。画个图理解一下:

/*** 希尔排序 - 直接排序的优化版* 时间复杂度:O(n^1.3)~O(1^1.5)* 空间复杂度:O(1)* 稳点性:不稳定*/public void shellSort(int[] arr){int gap = arr.length;while(gap > 1){gap /= 2;for (int i = gap; i < arr.length; i++) {int tmp = arr[i];int j = i - gap;for (; j >= 0; j -= gap) {if(arr[j] > tmp){arr[j+gap] = arr[j];}else{break;}}arr[j+gap] = tmp;}}}
三,选择排序
基本思想:每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。
/*** 选择排序* 时间复杂度:O(n^2)* 空间复杂度:O(1)* 稳定性:不稳定*/public void selectSort(int[] arr){for (int i = 0; i < arr.length; i++) {int minIndex = i;for (int j = i+1; j < arr.length; j++) {if(arr[minIndex] > arr[j]){minIndex = j;}}swap(arr,minIndex,i);}}public void swap(int[] arr, int i, int j){int tmp = arr[i];arr[i] = arr[j];arr[j] = tmp;}
四,冒泡排序
基本思想:根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。
/*** 冒泡排序* 时间复杂度:O(n^2)* 空间复杂度:O(1)* 稳定性:稳定*/public void bubbleSort(int[] arr){for (int i = 0; i < arr.length-1; i++) {boolean flg = true;for (int j = 0; j < arr.length-1-i; j++) {if(arr[j] > arr[j+1]){int tmp = arr[j];arr[j] = arr[j+1];arr[j+1] = tmp;flg = false;}}if(flg){break;}}}
五,快排
基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。
5.1 Hoare法

从整体看,这就像一颗二叉树,所以我们可以用类似二叉树遍历的递归来实现,代码如下:
/*** 快排* 时间复杂度:O(nlogN)* 空间复杂度:O(logN)* 稳定性:不稳定*/ public void quickSort(int[] arr, int left, int right){if(left > right) return;//递归终止条件int div = partition(arr, left, right);//得到基准值下标quickSort(arr,left,div-1);//递归基准值前面的值quickSort(arr,div+1,right);//递归基准值后面的值}public int partition(int[] arr, int left, int right){int tmp = left;int key = arr[left];while(left < right){//注意这里只能先遍历右边,否则基准值的前面就会存在 >基准值的值,//后面就会存在 <基准值的值// && = 号必须有,不然如果基准和R相同,就会出现死循环while(left < right && arr[right] >= key){right--;}while(left < right && arr[left] <= key){left++;}swap(arr,left,right);}swap(arr,tmp,left);return left;//or right}
5.2 挖坑法
与Hoare法类似,只不过它把基准的初始位置当作一个坑,查找右边,将右边的值赋给坑,将右边变成坑,再查找左边,将左边的值赋给坑,将左边变成坑,重复以上操作直到 L== R,将arr[L] = key。再往下面递归,这里就不画图讲解了,直接上代码:
public int partition(int[] arr, int left, int right){int tmp = arr[left];while(left < right){while(left < right && arr[right] >= tmp){//=必须有 , 必须是right先走right--;}arr[left] = arr[right];while(left < right && arr[left] <= tmp){left++;}arr[right] = arr[left];}arr[left] = tmp;return left;}
5.3 指针法
它的主要思想没变,还是找到基准值的下标位置,将其分成两份,依次类推,但是它寻找基准的方法很神奇,先看代码:
public int partition(int[] arr, int left, int right){int prev = left;int cur = left + 1;while(cur <= right){if(arr[cur] < arr[left] && (++prev) != cur ){swap(arr,prev,cur);}cur++;}swap(arr,left,prev);return prev;}

5.4 非递归写法
public void quickSortNor(int[] arr, int left, int right){Stack<Integer> ret = new Stack<>();ret.push(left);ret.push(right);while(!ret.empty()){right = ret.pop();left = ret.pop();int div = partition(arr,left,right);//找到基准的下标if(left + 1 < div){//基准左边有2+的元素ret.push(left);ret.push(div-1);}if(right-1 > div){//基准右边有2+的元素ret.push(div+1);ret.push(right);}}}
六,归并排序
基本思路:将一组数据分成等长的两份,再将每份分成等长的两份,直到每份数据的长度都为一,然后再逆推回去,每次逆推都要进行一次排序,直到变成一份。如图:

6.1 递归
可以通过子问题的思路来理解代码:先将前面的一半排序,再将后面的一半排序,最后将整体排序,它们的每一部分都可是这样操作,所以可以使用递归解决。
/*** 归并排序* 时间复杂度:O(nlogn)* 空间复杂度:O(n)* 稳定*/public void mergeSort(int[] arr, int left, int right){if(left >= right) return;int mid = left + (right - left)/2;mergeSort(arr,left,mid);// 前 n/2 排序mergeSort(arr,mid+1,right);// 后 n/2 排序merge(arr,left,right,mid);// 整体排序}public void merge(int[] arr, int left, int right, int mid){int s1 = left;int s2 = mid+1;int k = 0;int[] tmp = new int[right-left+1];while(s1 <= mid && s2 <= right){if(arr[s1] <= arr[s2]){tmp[k++] = arr[s1++];}else{tmp[k++] = arr[s2++];}}while(s1 <= mid){tmp[k++] = arr[s1++];}while (s2 <= right){tmp[k++] = arr[s2++];}for (int i = 0; i < tmp.length; i++) {arr[i+left] = tmp[i];}}
6.2 非递归
思路:直接将其分成一个一组,然后再两两组合,直到合成一体,就只有上面那张图的下半部分:

public void mergeSortNor(int[] arr){int gap = 1;while(gap < arr.length){for (int i = 0; i < arr.length; i+=2*gap) {int left = i;//相邻两段子数组的开始和末位下标 [left,mid] [mid+1,right]int mid = left + gap -1;int right = mid + gap;if(mid >= arr.length){//说明只有前面一段数组mid = arr.length - 1;}if(right >= arr.length){//说明后面的子数组数量少right = arr.length-1;}merge(arr,left,right,mid);}gap *= 2;}}
相关文章:
基本排序算法
目录 一,插入排序 二,希尔排序 三,选择排序 四,冒泡排序 五,快排 5.1 Hoare法 5.2 挖坑法 5.3 指针法 5.4 非递归写法 六,归并排序 6.1 递归 6.2 非递归 一,插入排序 基本思想&…...
python调用百度ai将图片/pdf识别为表格excel
python调用百度ai将图片识别为表格excel 表格文字识别(异步接口)图片转excel 表格文字识别V2图片/pdf转excel通用 表格文字识别(异步接口) 图片转excel 百度ai官方文档:https://ai.baidu.com/ai-doc/OCR/Ik3h7y238 使用的是表格文字识别(异步接口),同步…...
Ansible最佳实践之Playbook管理滚动更新
写在前面 理解不足小伙伴帮忙指正 傍晚时分,你坐在屋檐下,看着天慢慢地黑下去,心里寂寞而凄凉,感到自己的生命被剥夺了。当时我是个年轻人,但我害怕这样生活下去,衰老下去。在我看来,这是比死亡…...
基于Citespace、vosviewer、R语言的文献计量学可视化分析及SCI论文高效写作方法教程
详情点击链接:基于Citespace、vosviewer、R语言的文献计量学可视化分析技术及全流程文献可视化SCI论文高效写作方法 前言 文献计量学是指用数学和统计学的方法,定量地分析一切知识载体的交叉科学。它是集数学、统计学、文献学为一体,注重量…...
【MATLAB】GM(1,1) 灰色预测模型及算法
一、灰色预测模型概念 灰色预测是一种对含有不确定因素的系统进行预测的方法。 灰色预测通过鉴别系统因素之间发展趋势的相异程度,即进行关联分析,并对原始数据进行生成处理来寻找系统变动的规律,生成有较强规律性的数据序列,然后…...
Go重写Redis中间件 - Go实现Redis协议解析器
Go实现Redis协议解析器 Redis网络协议详解 在解决完通信后,下一步就是搞清楚 Redis 的协议-RESP协议,其实就是一套类似JSON、Protocol Buffers的序列化协议,也就是我们的客户端和服务端通信的协议 RESP定义了5种格式 简单字符串(Simple String) : 服务器用来返回简单的结…...
海外抖音Tiktok强势来袭,有些人半年赚别人十倍工资
TikTok作为一款流行的短视频社交应用程序,确实在全球范围内取得了很大的成功。许多人通过在TikTok上分享有趣、创意或有吸引力的视频内容,获得了广泛的关注和认可。一些用户甚至能够通过TikTok赚取高额的收入,远远超过传统职业所能获得的工资…...
devDept Eyeshot 2024 预告-Update-Crack
即将发布的版本 开发商在一个动态的环境中运作,事情可能会发生变化。本页提供的信息旨在概述 devDept 软件产品的总体方向。它仅供参考,不应作为做出任何决定性的依据。devDept Eyeshot 2024软件产品描述的任何特性或功能的开发、发布和时间安排仍由 dev…...
教雅川学缠论05-线段
线段需要满足下面4个条件: 1.是由3条笔,或者3条以上组成,同笔一样,线段也是有方向的 2.如果线段起始于向上笔,则终止与向上笔(一定不会终止与向下笔) 3.如果线段起始于向下笔,则终止…...
SpringBoot 配置⽂件
1.配置文件作用 整个项⽬中所有重要的数据都是在配置⽂件中配置的,⽐如: 数据库的连接信息(包含⽤户名和密码的设置);项⽬的启动端⼝;第三⽅系统的调⽤秘钥等信息;⽤于发现和定位问题的普通⽇…...
基于Python的电影票房爬取与可视化系统的设计与实现
博主介绍:✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专…...
Packet Tracer – 配置系统日志和 NTP
Packet Tracer – 配置系统日志和 NTP 目标 第 1 部分:配置系统日志服务 第 2 部分:生成日志记录事件 第 3 部分:手动设置交换机时钟 第 4 部分:配置 NTP 服务 第 5 部分:验证带时间戳的日志 拓扑图 场景 在本…...
TypeScript 联合类型,类型推断,类型断言
联合类型 取值可以为多种类型中的一个 function func(str: number | string):void{}类型断言 当变量需要调用某属性的时候,有不确定当前的类型是什么,可以使用类型断言; 类型断言的两种方式: 1,<类型> 变量名…...
到底叫 集合还是数组还是list还是列表?
1 总体上可以将数据结构分为数组和集合两种,而列表是一个泛指 数组:在Java中,数组是一种基本数据类型,可以用来存储同一类型的多个元素,数组的长度是固定的。例如:int[] arr new int[10];List:…...
LBERT论文详解
论文地址:https://arxiv.org/abs/2105.07148 代码地址:https://github.com/liuwei1206/LEBERT 模型创新 LEBRT采用句子中的词语对(论文中称为Char-Word Pair)的特征作为输入作者设计Lexicon adapter,在BERT的中间某一…...
C++终止cin输入while循环时多读取^Z或^D的问题
原代码: istream& operator>>(istream& is, map<string, int>&mm) {string ss"";int ii0;is >> ss>>ii;mm[ss]ii;return is; }int main() {map<string,int>msi;while(cin>>msi);return 0; } 问题&…...
c#[WebMethod]方法接收前端传入的JsonArray的方法
一、第一种方法:可以这样接收前端传入的jsonArray字符串到一个类的数组中,然后遍历该数组取值 这种方法需要创建PointConfig类 class PointConfig{public string ptcrossing { get; set; }public string ptcrossingId { get; set; }public string camId …...
WebService 报错 集锦
报错1:url错误 我的是调用的url的端口错误。调用esb的url的端口错了,导致报错。有的人是uri错了。例如: www.globalcoding.com:9001/SAP_saveProduct/1.0.0 写成了 www.globalcoding.com:9001/SAP_savePoduct/1.0.0 报错如下:…...
C++--菱形继承
1.什么是菱形继承 单继承:一个子类只有一个直接父类时称这个继承关系为单继承 多继承:一个子类有两个或以上直接父类时称这个继承关系为多继承 菱形继承的问题:菱形继承有数据冗余和二义性的问题,数据冗余是由于创建多个相同类型的…...
Vue 3:玩一下web前端技术(二)
前言 本章内容为VUE目录结构解析与相关工程技术讨论。 上一篇文章地址: Vue 3:玩一下web前端技术(一)_Lion King的博客-CSDN博客 下一篇文章地址: Vue 3:玩一下web前端技术(三)…...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
4. TypeScript 类型推断与类型组合
一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式,自动确定它们的类型。 这一特性减少了显式类型注解的需要,在保持类型安全的同时简化了代码。通过分析上下文和初始值,TypeSc…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...
数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !
我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...
