排序算法超详细代码和知识点整理(java版)
排序
1、冒泡排序
两层循环,相邻两个进行比较,大的推到后面去,一共比较“数组长度”轮,每一轮都是从第一个元素开始比较,每一轮比较都会将一个元素固定到数组最后的一个位置。【其实就是不停的把元素往后堆,数组剩余长度越来越少,直到堆到最后一个,数组都堆好排好序了】
if (arr == null || arr.length < 2) return;
for (int e = arr.length - 1; e > 0; e--) {for (int i = 0; i < e; i++) {if (arr[i] > arr[i + 1]) {swap(arr, i, i + 1); } } }
2、选择排序
也是比较**“数组长度-1”轮,但是每一轮中是将一个最值元素放在开头**,然后从这个更新过元素的位置往后继续开始此轮的选择最值过程【其实就是不停的从选择最小元素,然后往前堆,和冒泡正好相反,然后前面剩余空间越来越少,直到前面都堆好了排好序了】
if (arr == null || arr.length < 2) return;
for(int i=0; i<arr.length - 1; i++){int minIndex = i;for(int j=i+1; j<arr.length; j++){minIndex = arr[j] < arr[minIndex] ? j : minIndex;} swap(arr,i,minIndex);
}
3、插入排序
重点看当前索引指向的元素大小,去对比比当前索引小,也就是前面排好序的那一部分元素。找到合适的位置,然后插进去。这对比的次数明显变少,只用和【索引-1】前面的数进行比较。
if (arr == null || arr.length < 2) return;
for(int i = 1; i<arr.length; i++)for(int j = i-1; arr[j+1]<arr[j] && j >= 0; j--)swap(arr,j,j+1);
4、快速排序
本质是找个基准值,一般可以选取这段数组中的最后一个元素。然后将小于这个基准值的放在其左侧,大于的放在其右侧.
在遍历数组时,一般采用三指针法来实现。具体来说,我们使用一个左指针指向数组的左边界,用一个右指针指向数组的右边界。另外一个指针指向元素,用来遍历。
-
如果当前查找的索引值对应数据 arr [i] 小于基准值,那么这个值和左边界【左指针】的下一个进行交换,同时左指针右移;
-
如果大于基准值,就将其和右边界的前一个元素交换,同时左边界指针不动。索引 i 也不动,但是右指针左移
-
如果等于基准值,索引 i ++
public static void quickSort(int[] arr){if(arr == null || arr.length < 2)return;quickSort(arr,0,arr.length-1);
}public static void quickSort(int[] arr, int l, int r){if(l < r){int[] p = partition(arr,l,r); //作用就是将最后一个元素当作基准值,然后将大于基准值得放右边,小于的放左边//同时,返回一个基准信息,p[0]就是基准值中最左的一个【考虑到可能标志值会重复】,p[1]是最右侧quickSort(arr, l, p[0] - 1);quickSort(arr, p[1] + 1, r);}
}public static void partiton(int[] arr, int l, int r){ //l是左边界,int pivot = arr[r];int left = l -1;int right = r;while(l < right){ //arr[l],就用来记录逐步遍历数组中的元素if(arr[l] < pivot)swap(arr, ++left, l++); // 将小于等于pivot的元素交换到左边界的右侧else if(arr[l] > pivot){swap(arr, --right, l); // 将大小于等于pivot的元素交换到右边界的左侧}elsel++;}swap(arr, more, r); //最后将基准值转移到右指针位置return new int[] { less + 1, more };
}
5、归并排序
将数组按照中间的位置,划分成左右两部分,然后对这两部分进行扫描归并。准备两个指针,分别指向左部分的开头,以及有部分的开头。然后比较大小,按照比较结果,将结果放进一个临时开辟的数组中,最后将这个临时数组的元素再塞回去。
public static void mergeSort(int[] arr){if(arr == null || arr.length < 2)return;mergeSort(arr,0,arr.length-1);
}public static void mergeSort(int[] arr, int l, int r){if(l < r){int mid = l + ((r-l)>>1;mergeSort(arr, l, mid+1);mergeSort(arr, mid+1, r); merge(arr,l,mid,r);}
}public static void merge(int[] arr, int l, int mid, int r) {int[] help = new int[r - l + 1];int i = 0;int p1 = l;int p2 = mid + 1;while(p1 <= mid && p2 <= r){help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];}while (p1 <= m) {help[i++] = arr[p1++];}while (p2 <= r) {help[i++] = arr[p2++];}for (i = 0; i < help.length; i++) {arr[l + i] = help[i];}
}
6、堆排序
主要涉及两步骤:
1、构建堆【heapInsert】,2、输出堆顶元素,然后调整堆结构,以便于下一轮继续输出堆顶元素【heapify】
构建堆的过程就是不停的往上,也就是和自己的父节点、祖父节点…一直比较下去,如果想要大根堆,那就是只要大于父节点,那就和父节点交换,我们对数组的每一个元素都去单独构建一边。
调整堆,就是不停的往下。将堆顶元素和数组最后元素交换,由于当前数组经过构建堆过程后,已经是堆结构了。所以我们的堆顶元素肯定就是一个最值,交换过后,再重新调整堆即可。就是找到堆顶的孩子节点中最大的值,进行比较交换,一直比较到树的最后一层
public static void heapSort(int[] arr) { //这个是主函数,参数中的arr数组中存放的就是待排元素if (arr == null || arr.length < 2) {return;}for (int i = 0; i < arr.length; i++) { //这个函数是用于创建大根堆,为了之后输出堆顶元素就是最大值heapInsert(arr, i);}int size = arr.length; swap(arr, 0, --size); //这一步是为了将堆顶元素和最后一个元素互换位置,注意最后要自减 也就是说最后应该数组中元素是从小到大排序的(如果一开始是一个大根堆)while (size > 0) {heapify(arr, 0, size);swap(arr, 0, --size); //同上面道理}
}
public static void heapInsert(int[] arr, int index) { //这个函数比较好理解,就是一个循环,只要在创建堆结构过程中,新加入堆中的子节点比父节点元素大,就交换,最后形成的是大根堆while (arr[index] > arr[(index - 1) / 2]) {swap(arr, index, (index - 1) /2);index = (index - 1)/2 ; //这一步别忘记了,一直是往下走的,index这个表示父节点位置的标记变量也要向下走}
}
public static void heapify(int[] arr, int index, int size) {//这次函数中参数中要借助 堆的大小size(对应上面主函数中的每次输出一次堆顶元素后,大小减1)int left = index * 2 + 1;while (left < size) {int largest = left + 1 < size && arr[left + 1] > arr[left] ? left + 1 : left;//上面这一步是为了找到左右子节点,哪个最大,然后记录最大的那个下标largest = arr[largest] > arr[index] ? largest : index;if (largest == index) {break;}swap(arr, largest, index);index = largest;left = index * 2 + 1;}
}
public static void swap(int[] arr, int i, int j) { //就是一个交换函数,C++中直接用swap函数即可int tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; }
7、优先级队列
默认是小根堆
//小根堆。默认
PriorityQueue<Integer> heap = new PriorityQueue<>();
-
在左神算法讲解时举了一个例子,就是;
堆排序扩展题目: 已知一个几乎有序的数组,几乎有序是指,如果把数组排好顺序的话,每个元素移动的距离可以不超过k,并且k相对于数组来说比较小。请选择一个合适的排序算法针对这个数据进行排序。
这时候就需要借助 堆结构 一开始先将前k个数存放入此优先级队列,也就是堆结构,然后将堆顶元素返回,也就是用pop返回
这k个元素构成一个堆结构,找到这个堆中的小根堆的堆顶元素,就是当前最小的
因为每个元素移动的距离不超过k,所以可以理解为这前k个数中最小的一个属肯也是整体数据中最小的一个数字,把第k+1个数放进去,再次形成小根堆,那返回的堆顶元素就是第二小的元素
然后再重新从数组中取下一个元素,添加到堆中,自动就排好序形成相应的大根堆或者是小根堆
-
下面我用左神算法中的java 代码来展示,其中关键的地方都加了注释了:
public void sortedArrDistanceLessK(int[] arr, int k) {PriorityQueue<Integer> heap = new PriorityQueue<>(); //java中的优先级队列的定义方式int index = 0;for (; index < Math.min(arr.length, k); index++) {//万一k超出范围了,就选取数组长度当作边界值,min()的作用就是这个heap.add(arr[index]);}int i = 0;for (; index < arr.length; i++, index++) {heap.add(arr[index]); //上面那个for循环实际上没有取到第k个元素,所以先取arr[i] = heap.poll(); //然后再弹出堆顶元素}while (!heap.isEmpty()) {//数组最后一个元素也都加进堆结构后,剩下的就是将堆中的所有元素放依次弹出了arr[i++] = heap.poll();}
}
8、复杂度
- 冒泡:时间复杂度o(n^2) 空间复杂度O(1)(原地排序,不需要额外空间)
- 选择:时间复杂度o(n^2) 空间复杂度O(1)(原地排序,不需要额外空间)
- 插入:时间复杂度o(n^2) 空间复杂度O(1)(原地排序,不需要额外空间)
- 快速:时间复杂度o(nlogN) 空间复杂度平均情况下是O(log n),最坏情况下是O(n)。
- 归并:时间复杂度o(nlogN) 空间复杂度O(n)(需要额外的空间来合并子数组)
- 堆 :时间复杂度o(nlogN) 空间复杂度O(1)(原地排序)
相关文章:
排序算法超详细代码和知识点整理(java版)
排序 1、冒泡排序 两层循环,相邻两个进行比较,大的推到后面去,一共比较“数组长度”轮,每一轮都是从第一个元素开始比较,每一轮比较都会将一个元素固定到数组最后的一个位置。【其实就是不停的把元素往后堆&#…...
Java复习第十二天学习笔记(JDBC),附有道云笔记链接
【有道云笔记】十二 3.28 JDBC https://note.youdao.com/s/HsgmqRMw 一、JDBC简介 面向接口编程 在JDBC里面Java这个公司只是提供了一套接口Connection、Statement、ResultSet,每个数据库厂商实现了这套接口,例如MySql公司实现了:MySql驱动…...
Python从零到一构建GPT模型
只用Python和 torch框架,从零到一构建GPT模型,对大语言模型入门,了解GPT的内部网络结构,是一个很好示例。 Build_GPT_from_Scratch.ipynb...
V R虚拟现实元宇宙的前景|虚拟现实体验店加 盟合作|V R设备在线购买
VR(虚拟现实)技术作为一种新兴的技术,正在逐渐改变人们的生活和工作方式。随着技术的不断进步,人们对于元宇宙的概念也越来越感兴趣。元宇宙是一个虚拟世界,通过VR技术可以实现人们在其中进行各种活动和交互。 元宇宙的…...
大话设计模式之策略模式
策略模式是一种行为设计模式,它允许在运行时选择算法的行为。这种模式定义了一族算法,将每个算法都封装起来,并且使它们之间可以互相替换。 在策略模式中,一个类的行为或其算法可以在运行时改变。这种模式包含以下角色࿱…...
蓝桥杯23年第十四届省赛真题-三国游戏|贪心,sort函数排序
题目链接: 1.三国游戏 - 蓝桥云课 (lanqiao.cn) 蓝桥杯2023年第十四届省赛真题-三国游戏 - C语言网 (dotcpp.com) 虽然这道题不难,很容易想到,但是这个视频的思路理得很清楚: [蓝桥杯]真题讲解:三国游戏࿰…...
P15:PATH环境变量
为什么要配置环境变量 当我们打开DOS窗口,输入:javac,出现下面问题。 原因:windows操作系统在当前目录中无法找到javac命令文件。Windows操作系统是如何搜索硬盘上某一个命令? 首先从当前目录中搜索该命令如果当前目录…...
math模块篇(七)
文章目录 math.dist(p, q)math.hypot(*coordinates)math.sin(x)math.tan(x)math.degrees(x)math.radians(x)math.acosh(x)math.asinh(x)math.atanh(x) math.dist(p, q) 在Python的math模块中,并没有一个名为math.dist(p, q)的函数。可能你是想要计算两点p和q之间的…...
wordpress插件,免费的wordpress插件
WordPress作为世界上最受欢迎的内容管理系统之一,拥有庞大的插件生态系统,为用户提供了丰富的功能扩展。在内容创作和SEO优化方面,有一类特殊的插件是自动生成原创文章并自动发布到WordPress站点的工具。这些插件能够帮助用户节省时间和精力&…...
Remote Desktop Manager for Mac:远程桌面管理软件
Remote Desktop Manager for Mac,是远程桌面管理的理想之选。它集成了多种远程连接技术,无论是SSH、RDP还是VNC,都能轻松应对,让您随时随地安全访问远程服务器和工作站。 软件下载:Remote Desktop Manager for Mac下载…...
如何撰写研究论文
SEVENTYFOUR/SHUTTERSTOCK 即使对于有经验的作家来说,将数月或数年的研究浓缩到几页纸中也是一项艰巨的任务。作者需要在令人信服地解决他们的科学问题和详细地呈现他们的结果之间找到最佳平衡点,以至于丢失了关键信息。他们必须简明扼要地描述他们的方…...
数据结构
一、栈 先进后出 二、队列 先进先出 三、数组 查询快,增加修改慢 四、链表 查询慢,增加修改慢 五、二叉树 节点: 查找二叉树 二叉查找树的特点 二叉查找树,又称二叉排序树或者二叉搜索树 每一个节点上最多有两个子节点 左子树上所…...
动态规划相关题目
文章目录 1.动态规划理论基础2.斐波那契数3.爬楼梯4.使用最小花费爬楼梯5.不同路径6.不同路径 II7. 整数拆分8. 不同的二叉搜索树 1.动态规划理论基础 1.1 什么是动态规划? 动态规划,英文:Dynamic Programming,简称DP,如果某一…...
iOS - Runtime - Class-方法缓存(cache_t)
文章目录 iOS - Runtime - Class-方法缓存(cache_t)1. 散列表的存取值 iOS - Runtime - Class-方法缓存(cache_t) Class内部结构中有个方法缓存(cache_t),用散列表(哈希表)来缓存曾经调用过的方法,可以提高…...
2014年认证杯SPSSPRO杯数学建模B题(第一阶段)位图的处理算法全过程文档及程序
2014年认证杯SPSSPRO杯数学建模 B题 位图的处理算法 原题再现: 图形(或图像)在计算机里主要有两种存储和表示方法。矢量图是使用点、直线或多边形等基于数学方程的几何对象来描述图形,位图则使用像素来描述图像。一般来说&#…...
【物联网项目】基于ESP8266的家庭灯光与火情智能监测系统——文末完整工程资料源码
目录 系统介绍 硬件配置 硬件连接图 系统分析与总体设计 系统硬件设计 ESP8266 WIFI开发板 人体红外传感器模块 光敏电阻传感器模块 火焰传感器模块 可燃气体传感器模块 温湿度传感器模块 OLED显示屏模块 系统软件设计 温湿度检测模块 报警模块 OLED显示模块 …...
Unity中控制帧率的思考
如何控制帧率: 在Unity中,你可以通过设置Application.targetFrameRate来限制帧率。 例如,如果你想将帧率限制为16帧, 你可以在你的代码中添加以下行: Application.targetFrameRate 16; 通常,这行代码会放在…...
阿里云子域名配置,且不带端口访问
进入阿里云控制台,创建一个SSL证书 # 域名名称child.domain.com创建完成后,将返回主机记录以及记录值,保存好,用于下一步使用 创建DNS解析 创建DNS的TXT类型解析 选择记录类型:TXT 填写主机记录:_dnsa…...
C#-ConcurrentDictionary用于多线程并发字典
ConcurrentDictionary 是 .NET Framework 中用于多线程并发操作的一种线程安全的字典集合类。它提供了一种在多个线程同时访问和修改字典时保持数据一致性的机制。 以下是 ConcurrentDictionary 类的一些重要特性和用法: 线程安全性:ConcurrentDictiona…...
深入探讨多线程编程:从0-1为您解释多线程(下)
文章目录 6. 死锁6.1 死锁原因 6.2 避免死锁的方法加锁顺序一致性。超时机制。死锁检测和解除机制。 6. 死锁 6.1 死锁 原因 系统资源的竞争:(产生环路)当系统中供多个进程共享的资源数量不足以满足进程的需要时,会引起进程对2…...
深度学习pytorch——减少过拟合的几种方法(持续更新)
1、增加数据集 2、正则化(Regularization) 正则化:得到一个更加简单的模型的方法。 以一个多项式为例: 随着最高次的增加,会得到一个更加复杂模型,模型越复杂就会更好的拟合输入数据的模型(图-1)&#…...
排序第五篇 归并排序
一 简介 归并排序(Merge Sort) 的基本思想是: 首先将待排序文件看成 n n n 个长度为1的有序子文件, 把这些子文件两两归并, 得到 n 2 \frac{n}{2} 2n 个长度为 2 的有序子文件; 然后再把这 n 2 \frac{n}{2} 2n 个有序的子…...
【Win】使用PowerShell和Webhooks轻松发送消息至Microsoft Teams
Microsoft Teams是一款由微软开发的团队协作和通讯工具。如果您对这个名字还不太熟悉,那么现在就是一个了解它的好时机。微软将Teams定位为其之前Skype for Business解决方案的继任者,并且它也提供了与其他基于频道的通讯应用程序(例如Slack、…...
ESCTF-OSINT赛题WP
这你做不出来?check ESCTF{湖北大学_嘉会园食堂} 这个识图可以发现是 淡水渔人码头 但是 osint 你要发现所有信息 聊天记录说国外 同时 提示给了美国 你综合搜索 美国 渔人码头 在美国旧金山的渔人码头(英语:Fisherman’s Wharf)是一个著名旅…...
2024蓝桥杯省赛保奖突击班-Day2-前缀和、差分、尺取_笔记_练习题解
3月25日-课堂笔记 前缀和预处理 O ( n ) \mathcal{O}(n) O(n) s[1] a[1]; for(int i 2; i < n; i)s[i] s[i - 1] a[i];利用前缀和查询区间和 O ( 1 ) O(1) O(1) long long calc(int l, int r) {return l 1 ? s[r] : s[r] - s[l - 1]; }差分序列的求法 c[1] a[…...
C++基础之虚函数(十七)
一.什么是多态 多态是在有继承关系的类中,调用同一个指令(函数),不同对象会有不同行为。 二.什么是虚函数 概念:首先虚函数是存在于类的成员函数中,通过virtual关键字修饰的成员函数叫虚函数。 性质&am…...
快速入门Kotlin①基本语法
前言 23年底读了一遍“Kotlin官方文档”,官方文档大而全,阅读下来,大有裨益。 此系列文章的目的是记录学习进程,同时,若能让读者迅速掌握重点内容并快速上手,那就再好不过了。 函数 带有两个 Int 参数、…...
【理解指针(四)】
文章目录 一、指针数组二、指针数组来模拟二维数组三、字符指针变量注意: 字符串的例子(曾经的一道笔试题) 四、数组指针变量1、什么是数组指针变量2、数组指针怎么初始化 五、二维数组传参的本质六、函数指针1、什么是函数指针变量2、函数的…...
Ribbon简介
目录 一 、概念介绍 1、Ribbon是什么 2、认识负载均衡 2.1 服务器端的负载均衡 2.2 客户端的负载均衡 3、Ribbon工作原理 4、Ribbon的主要组件 IClientConfig ServerList ServerListFilter IRule Iping ILoadBalancer ServerListUpdater 5、Ribbon支持…...
【感悟《剑指offer》典型编程题的极练之路】02字符串篇!
个人主页:秋风起,再归来~ 文章所属专栏:《剑指offer》典型编程题的极练之路 个人格言:悟已往之不谏,知来者犹可追 克心守己,…...
word做招聘网站/网站收录优化
🎇Linux: 博客主页:一起去看日落吗分享博主的在Linux中学习到的知识和遇到的问题博主的能力有限,出现错误希望大家不吝赐教分享给大家一句我很喜欢的话: 看似不起波澜的日复一日,一定会在某一天让你看见坚持…...
网站建设 数据库/谷歌搜索引擎入口2022
项目组成员在针对要开发的系统做需求调研后,就要编写对应的需求说明书。 作为软件工程师,你就得知道需求分析说明书和需求规格说明书的区别,以期在正确的时候编写正确的需求文档。 两者有何不同: (1)面向…...
html商城网站源码/湖南关键词优化首选
与 UpdatePanel 控件不兼容的控件 下面的 ASP.NET 控件与部分页更新不兼容,因此,不能用在 UpdatePanel 控件内: 在以下几种情况下的 Treeview 控件:一种是当回调不是作为异步回发的一部分启用时;一种是您直接将样式设置…...
唐山高端网站建设/国内重大新闻10条
author:skate time:2013/03/01 mysql在线无性能影响删除7G大表 如何在mysql数据库里删除7G(或更大)大表,使其又不影响服务器的io,导致性能下降影响业务。先不说其是mysql表,就是普通文件,如果直接rm删除&a…...
做pc端网站报价/如何在百度上发布广告
1.根据php版本下载对应的swoole扩展版本进行编译安装,步骤安装官方手册进行安装即可2.创建一个异步服务器程序Server,只能用于php-cli环境,以thinkphp5为例复制public目录下的入口文件index.php到cli目录cli.php里4.application目录下创建cli…...
厦门网站建设外包维护/百度云资源共享
2019独角兽企业重金招聘Python工程师标准>>> 准备工作3个虚拟机节点的构成如下 :安装步骤操作过程1、安装包已经上传至其中1个节点。 2、解压缩安装包 命令:unzip rocketmq-all-4.0.0-incubating-bin-release.zip 解压缩之后如下:…...