十大基础算法
一、选择排序
过程简单描述:
首先,找到数组中最小的那个元素,其次,将它和数组的第一个元素交换位置(如果第一个元素就是最小元素那么它就和自己交换)。其次,在剩下的元素中找到最小的元素,将它与数组的第二个元素交换位置。如此往复,直到将整个数组排序。这种方法我们称之为选择排序。
为方便理解我还准备了动图:
.

public class SelectionSort {public static void main(String[] args) {int[] arr = {5, 3, 6, 8, 1, 7, 9, 4, 2};//定义内外两层循环,从最外层循环第一个值开始匹配,内层循环从外层循环加以开始向后匹配//如果遇到小的值就进行交换//外层循环到倒数第二为止,内层循环到倒数第一为止for (int i = 0; i < arr.length-1; i++) {int min = i;for (int j = i+1; j < arr.length; j++) {if(arr[i]>=arr[j]){min = j;int temp = arr[i];arr[i] = arr[min];arr[j] = temp;}}}CommonUtils.print(arr);}
}
性质:1、时间复杂度:O(n2) 2、空间复杂度:O(1) 3、非稳定排序 4、原地排序
二、插入排序
我们在玩打牌的时候,你是怎么整理那些牌的呢?一种简单的方法就是一张一张的来,将每一张牌插入到其他已经有序的牌中的适当位置。当我们给无序数组做排序的时候,为了要插入元素,我们需要腾出空间,将其余所有元素在插入之前都向右移动一位,这种算法我们称之为插入排序。
过程简单描述:
1、从数组第2个元素开始抽取元素。
2、把它与左边第一个元素比较,如果左边第一个元素比它大,则继续与左边第二个元素比较下去,直到遇到不比它大的元素,然后插到这个元素的右边。
3、继续选取第3,4,….n个元素,重复步骤 2 ,选择适当的位置插入。
为方便理解我还准备了动图:

public class InsertionSort {public static void main(String[] args) {int[] a = { 9, 3, 1, 4, 6, 8, 7, 5, 2 };for (int i = 1; i < a.length; i++) {//内层比较是从外层的赋值为起始点//该值会和它前面的值比较,如果比前面的值小就交换for (int j = i;j>0; j--) {if(a[j]<a[j-1]){CommonUtils.swap(a,j,j-1);}}}CommonUtils.print(a);}
}
三、冒泡排序
1、把第一个元素与第二个元素比较,如果第一个比第二个大,则交换他们的位置。接着继续比较第二个与第三个元素,如果第二个比第三个大,则交换他们的位置….
我们对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样一趟比较交换下来之后,排在最右的元素就会是最大的数。
除去最右的元素,我们对剩余的元素做同样的工作,如此重复下去,直到排序完成。
为方便理解我还准备了动图:

public class BubbleSort {public static void main(String[] args) {int[] arr = {5, 3, 6, 8, 1, 7, 9, 4, 2};for (int i = 0; i < arr.length; i++) {//内层循环像指针一样指导着程序运行for (int j = 0; j < arr.length-i-1; j++) {if(arr[j]>arr[j+1]){CommonUtils.swap(arr,j,j+1);}}}CommonUtils.print(arr);}
}
四、希尔排序
希尔排序可以说是插入排序的一种变种。无论是插入排序还是冒泡排序,如果数组的最大值刚好是在第一位,要将它挪到正确的位置就需要 n - 1 次移动。也就是说,原数组的一个元素如果距离它正确的位置很远的话,则需要与相邻元素交换很多次才能到达正确的位置,这样是相对比较花时间了。
希尔排序就是为了加快速度简单地改进了插入排序,交换不相邻的元素以对数组的局部进行排序。
希尔排序的思想是采用插入排序的方法,先让数组中任意间隔为 h 的元素有序,刚开始 h 的大小可以是 h = n / 2,接着让 h = n / 4,让 h 一直缩小,当 h = 1 时,也就是此时数组中任意间隔为1的元素有序,此时的数组就是有序的了。
为方便理解我还准备了图片:

public class ShellSort {public static void main(String[] args) {int[] arr = {5, 3, 6, 8, 1, 7, 9, 4, 2};int h = arr.length/2;for (int gap = h; gap > 0; gap--) {//间隔的循环for (int j = 0; j < arr.length-gap; j++) {if(arr[j]>arr[j+gap]){CommonUtils.swap(arr,j,j+gap);}}}CommonUtils.print(arr);}
}
五、归并排序
将一个大的无序数组有序,我们可以把大的数组分成两个,然后对这两个数组分别进行排序,之后在把这两个数组合并成一个有序的数组。由于两个小的数组都是有序的,所以在合并的时候是很快的。
通过递归的方式将大的数组一直分割,直到数组的大小为 1,此时只有一个元素,那么该数组就是有序的了,之后再把两个数组大小为1的合并成一个大小为2的,再把两个大小为2的合并成4的 ….. 直到全部小的数组合并起来。
为方便理解我还准备了动图:

public class MergeSort {public static void main(String[] args) {int[] arr = {1,4,7,8,3,6,9};sort(arr, 0, arr.length-1);CommonUtils.print(arr);}static void sort(int[] arr, int left, int right) {if(left==right){return;}int mid = left + (right-left)/2;sort(arr,left,mid);sort(arr,mid+1,right);merge(arr,left,mid+1,right);}//先定义合并的方法static void merge(int[] arr, int leftPtr, int rightPtr, int rightBound) {int i = leftPtr;int j = rightPtr;int mid = rightPtr -1;int[] temp = new int[rightBound - leftPtr + 1];int tempPtr = 0;//进行比较赋值while (i<=mid&&j<=rightBound){if(arr[i]>arr[j]){temp[tempPtr]=arr[j];j++;tempPtr++;}else {temp[tempPtr]=arr[i];i++;tempPtr++;}}//将未放入临时数组的数放入临时数组while(i<=mid) temp[tempPtr++] = arr[i++];while(j<=rightBound) temp[tempPtr++] = arr[j++];//数组复制for (int i1 = 0; i1 < temp.length; i1++) {arr[leftPtr+i1]=temp[i1];}}
}
六、快速排序
我们从数组中选择一个元素,我们把这个元素称之为中轴元素吧,然后把数组中所有小于中轴元素的元素放在其左边,所有大于或等于中轴元素的元素放在其右边,显然,此时中轴元素所处的位置的是有序的。也就是说,我们无需再移动中轴元素的位置。
从中轴元素那里开始把大的数组切割成两个小的数组(两个数组都不包含中轴元素),接着我们通过递归的方式,让中轴元素左边的数组和右边的数组也重复同样的操作,直到数组的大小为1,此时每个元素都处于有序的位置。
为方便理解我还准备了动图:

public class QuickSort {public static void main(String[] args) {int[] arr = {1,5,7,6,4};sort(arr,0,arr.length-1);CommonUtils.print(arr);}static void sort(int[] arr, int leftBound, int rightBound) {if(leftBound>=rightBound) {return;}int mid = partition(arr, leftBound, rightBound);sort(arr,leftBound,mid-1);sort(arr,mid+1,rightBound);}static int partition(int[] arr, int leftBound, int rightBound) {int left = leftBound;int mid = rightBound;int right = rightBound-1;while (left<=right){//1、这两个指针分别寻找小于标杆和大于标杆的数,找到以后指针停止//2、交换两边指针停止位置的数//3、将标杆放到中间的位置while (left<=right&&arr[left]<=arr[mid]){left++;}while (left<=right&&arr[right]>arr[mid]){right--;}if(left<right){CommonUtils.swap(arr,left,right);}}//把标杆放中间CommonUtils.swap(arr,left,rightBound);return left;}
}
七、计数排序
计数排序是一种适合于最大值和最小值的差值不是不是很大的排序。
基本思想:就是把数组元素作为数组的下标,然后用一个临时数组统计该元素出现的次数,例如 temp[i] = m, 表示元素 i 一共出现了 m 次。最后再把临时数组统计的数据从小到大汇总起来,此时汇总起来是数据是有序的。
为方便理解我还准备了动图:

public class CountSort {public static void main(String[] args) {int[] arr = {2, 4, 2, 3, 7, 1, 1, 0, 0, 5, 6, 9, 8, 5, 7, 4, 0, 9};int[] result = sort(arr);CommonUtils.print(result);}public static int[] sort(int[] arr) {int[] temp = new int[10];for (int a : arr) {temp[a]++;}int[] result = new int[arr.length];int r = 0;for (int i = 0; i < temp.length; i++) {while (temp[i]>0){result[r]=i;r++;temp[i]--;}}return result;}
}
八、桶排序
桶排序就是把最大值和最小值之间的数进行瓜分,例如分成 10 个区间,10个区间对应10个桶,我们把各元素放到对应区间的桶中去,再对每个桶中的数进行排序,可以采用归并排序,也可以采用快速排序之类的。
之后每个桶里面的数据就是有序的了,我们在进行合并汇总。
为方便理解我还准备了图片:

public class BucketSort {public static void main(String[] args) {int[] arr = {2, 4, 2, 3, 7,0};int[] result = sort(arr);CommonUtils.print(result);}public static int[] sort(int[] arr) {int max = findMax(arr);int mini = findMini(arr);int group = (max-mini)/5+1;List<List<Integer>> totalBucket = new LinkedList<>();//初始化桶for (int i = 0; i < group; i++) {totalBucket.add(new LinkedList<Integer>());}for (int i = 0; i < arr.length; i++) {//得到所在区间int i1 = (arr[i] - mini) / (max - mini);//向所在区间添加元素totalBucket.get(i1).add(arr[i]);}//复制结果for (List<Integer> integers : totalBucket) {Collections.sort(integers);}//复制结果int[] result = new int[arr.length];int r = 0;for (int i = 0; i < totalBucket.size(); i++) {for (int i1 = 0; i1 < totalBucket.get(i).size(); i1++) {result[r]= totalBucket.get(i).get(i1);r++;}}return result;}public static int findMax(int[] arr) {int max = arr[0];for (int i : arr) {if(i>max){max = i;}}return max;}public static int findMini(int[] arr) {int mini = arr[0];for (int i : arr) {if(i<mini){mini = i;}}return mini;}
}
九、基数排序
基数排序的排序思路是这样的:先以个位数的大小来对数据进行排序,接着以十位数的大小来多数进行排序,接着以百位数的大小……
排到最后,就是一组有序的元素了。不过,他在以某位数进行排序的时候,是用“桶”来排序的。
由于某位数(个位/十位….,不是一整个数)的大小范围为0-9,所以我们需要10个桶,然后把具有相同数值的数放进同一个桶里,之后再把桶里的数按照0号桶到9号桶的顺序取出来,这样一趟下来,按照某位数的排序就完成了
为方便理解我还准备了动图:

public class RadioSort {public static void main(String[] args) {int[] arr = {5, 3, 6, 8, 100, 7, 9, 4, 20};sort(arr);CommonUtils.print(arr);}public static int[] sort(int[] arr) {if(arr==null||arr.length==2) {return arr;}int max = findMax(arr);int num = 1;while (max/10>0){max= max/10;num++;}List<List<Integer>> totalBucket = new LinkedList<>();//初始化桶for (int i = 0; i < 10; i++) {totalBucket.add(new LinkedList<Integer>());}for (int i = 0; i < num; i++) {//放入对应的桶for (int j = 0; j < arr.length; j++) {int location = (arr[j] / (int)Math.pow(10,i)) % 10;totalBucket.get(location).add(arr[j]);}int k = 0;for (List<Integer> integers : totalBucket) {for (Integer integer : integers) {arr[k++]=integer;}integers.clear();}}return arr;}public static int findMax(int[] arr) {int max = arr[0];for (int i : arr) {if(i>max){max = i;}}return max;}
}
十、堆排序
堆的特点就是堆顶的元素是一个最值,大顶堆的堆顶是最大值,小顶堆则是最小值。
堆排序就是把堆顶的元素与最后一个元素交换,交换之后破坏了堆的特性,我们再把堆中剩余的元素再次构成一个大顶堆,然后再把堆顶元素与最后第二个元素交换….如此往复下去,等到剩余的元素只有一个的时候,此时的数组就是有序的了。
为方便理解我还准备了动图:

public class HeadSort {public static void main(String[] args) {int[] arr = {5, 3, 6, 8, 100, 7, 9, 4, 20};int n = arr.length;//构建大顶堆for (int i = (n - 2) / 2; i >= 0; i--) {sort(arr, i, n - 1);}//进行堆排序for (int i = n - 1; i >= 1; i--) {// 把堆顶元素与最后一个元素交换int temp = arr[i];arr[i] = arr[0];arr[0] = temp;// 把打乱的堆进行调整,恢复堆的特性sort(arr, 0, i - 1);}CommonUtils.print(arr);}public static void sort(int[] arr,int parent, int n) {int child = 2*parent+1;while (child<n){//如果右节点大于左节点这把指针只想左节点if(child+1<n&&arr[child]<arr[child+1]){child++;}//比较子节点和父节点的大小if(arr[child]>arr[parent]){CommonUtils.swap(arr,child,parent);}parent = child;child = 2*parent+1;}}}
总结
公共代码:
public class CommonUtils {public static void print(int[] arr) {for(int i=0; i<arr.length; i++) {System.out.print(arr[i] + " ");}}public static void swap(int[] arr, int i, int j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}
}
性质:
用一张图汇总了10大排序算法的性质

参考文章:
堆排序详细图解(通俗易懂)_右大臣的博客-CSDN博客
https://www.cnblogs.com/itsharehome/p/11058010.html
相关文章:
十大基础算法
一、选择排序 过程简单描述: 首先,找到数组中最小的那个元素,其次,将它和数组的第一个元素交换位置(如果第一个元素就是最小元素那么它就和自己交换)。其次,在剩下的元素中找到最小的元素,将它与数组的第二…...
Java---第八章(字符串-----String,StringBuilder 和 StringBuffer)
Java---第八章 字符串String字符串的常用方法StringBuilder和StringBuffer常用方法 对比String 和StringBuilder 和 StringBuffer 字符串 String 特性: String 类位于java.lang包中,无需引入,可直接使用String 类是由final修饰的ÿ…...
k8s集群的部署
【1】安装docker systemctl enable docker所有节点均需要安装docker,并且使其开机自启,每个节点均部署镜像加速器 【2】配置k8s的yum文件 [rootk8s1 ~]# cd /etc/yum.repos.d/ [rootk8s1 yum.repos.d]# vim k8s.repo [rootk8s1 yum.repos.d]# cat k8s.repo [k8s…...
设计模式——观察者模式
文章目录 1 概述2 实现3 总结 1 概述 观察者模式可以分为观察者和被观察者,观察者通过注册到一个被观察者中,也可视为订阅,当被观察者的数据发生改变时,会通知到观察者,观察者可以据此做出反应。 可以类比订阅报纸&am…...
在Debian 12 上安装 PHP 5.6, 7.4
环境:Debian 12 Debian 12 默认的PHP版本为 8.2 如果直接安装php7.4就出现下面的报错: sudo apt-get install libapache2-mod-php7.4 php7.4 php7.4-gd php7.4-opcache php7.4-mbstring php7.4-xml php7.4-json php7.4-zip php7.4-curl php7.4-imap p…...
微服务——统一网关Getway
为什么需要网关? 网关的两种实现: 网关Getway——快速入门 步骤一 网关背身也是一个微服务,需要注册到nacos中去 步骤二 成功运行后 可以通过网关进行请求转发到对应服务。 流程如下: 路由断言工厂 网关路由可以配置的东西有如下。 spri…...
[ELK安装篇]:基于Docker虚拟容器化(主要LogStash)
文章目录 一:前置准备-(参考之前博客):1.1:准备Elasticsearch和Kibana环境:1.1.1:地址:https://blog.csdn.net/Abraxs/article/details/128517777 二:Docker安装LogStash(数据收集引擎ÿ…...
纪录片《打铁文艺社》:从全美高中生电影节到多项国际赞誉,聚焦城市公共艺术的蜕变之路
7月21日,在全美高中生电影节(All American High School Film Festival,AAHSFF)公布的入围名单中,一部取材于中国深圳的纪录片《打铁文艺社Datie: The Art Tribe of Tiegang》以其深刻的主题和精良的制作,引…...
VLAN---虚拟局域网
VLAN— 虚拟局域网 LAN—局域网 MAN—城域网 WAN—广域网 1.一个VLAN相当于是一个广播域 VLAN—通过路由器和交换机协同工作后,将原本的一个广播域逻辑上,拆 分为多个虚拟的广播域。 VLAN配置: 1.创建VLAN VID—VLAN ID------用来区分和…...
新的CoolSiC™槽沟MOSFET技术,用于低栅氧化物应力和高性能
标题:The new CoolSiC™ Trench MOSFET Technology for Low Gate Oxide Stress and High Performance UPS(Uninterruptible Power Supply)系统也称不间断电源系统,是一种能够提供电力备用的设备,当主电源出现故障或停…...
【开源项目】低代码数据可视化开发平台-Datav
Datav 基本介绍 Datav是一个Vue3搭建的低代码数据可视化开发平台,将图表或页面元素封装为基础组件,无需编写代码即可完成业务需求。 它的技术栈为:Vue3 TypeScript4 Vite2 ECharts5 Axios Pinia2 在线预览 账号: admin 密码: 123123预…...
【自动话化运维】Ansible常见模块的运用
目录 一、Ansible简介二、Ansible安装部署2.1环境准备 三、ansible 命令行模块3.1.command 模块3.2.shell 模块3.3.cron 模块3.4.user 模块3.5.group 模块3.6.copy 模块3.7.file 模块8ÿ…...
深入理解C语言中的字符指针初始化与用法
字符指针初始化 - C 语言详解 目录 1. 介绍 2. 字符指针初始化的基础 3. 使用 const 关键字的字符指针初始化 4. C 语言与 C 在字符指针初始化的差异 5. 常见陷阱与最佳实践 6. 进阶概念:指针算术与动态内存分配 7. 字符串函数与字符指针 8. 结论介绍 在 C 语言中…...
es添加索引命令行和浏览器添加索引--图文详解
一、添加索引 创建索引 curl -X PUT "localhost:9200/my-index-00001?pretty" 获取索引 curl -X GET "localhost:9200/my-index-000001?pretty" 获取全部的索引 curl -X GET "http://localhost:9200/_cat/indices?v" 获取索引映射 cur…...
Java 大数字运算之 BigDecimal 类
在 Java 中提供了用于大数字运算的类,即 java.math.BigInteger 类和 java.math.BigDecimal 类。这两个类用于高精度计算,其中 BigInteger 类是针对整型大数字的处理类,而 BigDecimal 类是针对大小数的处理类。今天主要讲一下 BigDecimal 类 …...
MySQL 8.0 OCP (1Z0-908) 考点精析-架构考点1:二进制日志文件(Binary log)
文章目录 MySQL 8.0 OCP (1Z0-908) 考点精析-架构考点1:二进制日志文件(Binary log)MySQL二进制日志(Binary log)二进制日志文件的相关配置二进制日志文件的相关参数的说明二进制日志的格式设置二进制日志的格式 二进制…...
MY.CNF
# [client] port 3306 socket /var/lib/mysql/mysql.sock [mysql] prompt "\umysqldb \R:\m:\s [\d]> " no_auto_rehash loose-skip-binary-as-hex [mysqld] user mysql port 3306 #主从复制或MGR集群中,server_id记得要不同 #另外…...
SpringBoot IOC与AOP(一)
IOC AOP 一、 分层解耦 内聚: 软件中各个功能模块内部的功能联系 耦合: 衡量软件中各个层/模块之间的依赖、关联的程度 软件设计原则:高内聚、低耦合 控制反转:Inversion Of Control,简称IOC。对象的创建控制权由程序自身转移到…...
JVM运行时数据区——方法区的垃圾回收
方法区的垃圾回收主要是两部分:运行时常量池中废弃的常量和不在使用的类。 类卸载(将不在使用的类回收)的条件: 该类的所有实例均被回收。 加载该类的类加载器被回收(一般很难满足)。 类对象不再引用,通过反射也获取不到。...
LeetCode213.House-Robber-II<打家劫舍II>
题目: 思路: 在版本一中增加了一个条件 那就是首尾相关联。那么只需要进行两次循环即可。 第一次是循环是偷第一家的 那么循环到n-1 截至 并且保存一个cmp 第二次循环是不偷第一家的 循环到n截至。然后比较cmp 与 dp [n] 的最大值即可。 代码是&#…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
WPF八大法则:告别模态窗口卡顿
⚙️ 核心问题:阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程,导致后续逻辑无法执行: var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题:…...
