【JAVA】经典排序算法,注释详细+可直接运行
package com.example.demo.server;import org.junit.Test;import java.util.Arrays;/*** 十大排序算法*/
public class Sort {@Testpublic void test() {int[] array = {3, 44, 5, 18, 43, 66, 87, 24, 35};System.out.println(Arrays.toString(heapSort(array)));}/*** 8、计数排序* 适合一定范围内,有重复数据的排序* <p>* 速记:记录数组的最小最大值的长度,开辟新数组,count++,最后再遍历* <p>* 稳定;o(n+k)** @param array* @return*/public int[] countingSort(int[] array) {int min = array[0], max = array[0];for (int i = 0; i < array.length; i++) {min = Math.min(min, array[i]);max = Math.max(max, array[i]);}int[] tmp = new int[max - min + 1];for (int i = 0; i < array.length; i++) {tmp[array[i] - min]++;}int index = 0;for (int i = 0; i < tmp.length; i++) {int count = tmp[i];while (count > 0) {array[index] = i + min;index++;count--;}}return array;}/*** 7、堆排序(完全二叉树)* <p>* 不稳定;平均时间复杂度:o(nLogn)** @param array* @return*/public int[] heapSort(int[] array) {// 创建堆for (int i = (array.length - 1) / 2; i >= 0; i--) {adjustHeap(array, i, array.length);}// 堆顶堆尾交换+调整堆for (int i = array.length - 1; i > 0; i--) {int tmp = array[0];array[0] = array[i];array[i] = tmp;adjustHeap(array, 0, i);}return array;}private void adjustHeap(int[] array, int parent, int length) {int tmp = array[parent];int lChild = 2 * parent + 1;while (lChild < length) {int rChild = lChild + 1;// 找到子节点最大的数if (rChild < length && array[lChild] < array[rChild]) {lChild = rChild;}// 如果根最大,直接结束if (tmp >= array[lChild]) {break;}// 调整堆array[parent] = array[lChild];parent = lChild;lChild = 2 * lChild + 1;}array[parent] = tmp;}/*** 6、快速排序* 快排三步骤:选择基准值,分割操作返回中间下标,根据下标分成左右两边递归快排* 每趟排序后,左边的数都比基准值小,右边的数都比基准值大,即确定了基准值的位置* <p>* 不稳定;平均时间复杂度:o(nLogn)* <p>* 速记:左++右-- 指针,找到并返回基准值下标函数,根据下标分割(下标不参与),左边递归,右边递归** @param array* @return*/public int[] quickSort(int[] array, int left, int right) {if (array == null || left >= right || array.length <= 1) {return array;}int mid = partition(array, left, right); // 返回基准值下标quickSort(array, left, mid - 1);quickSort(array, mid + 1, right);return array;}private int partition(int[] array, int left, int right) {int base = array[right]; //以右边值为基准值while (left < right) {while (left < right && array[left] <= base) {left++;}int tmp = array[left];array[left] = array[right];array[right] = tmp;while (left < right && array[right] >= base) {right--;}tmp = array[right];array[right] = array[left];array[left] = tmp;}return left; // 返回基准值下标}/*** 5、归并排序* <p>* 递归的对左半部分排序,递归对右半部分排序,最后左右指针移动合并在一块* <p>* 稳定;平均时间复杂度:o(nLogn)* <p>* 速记:找到中点,左边递归,右边递归,新开数组空间合并left+right,若有剩余元素,一次性添加** @param array* @return*/public int[] mergeSort(int[] array) {int length = array.length;if (length <= 1) {return array;}int mid = length / 2;int[] left = Arrays.copyOfRange(array, 0, mid);// Arrays.copyOfRange 数组截取 [from,to)int[] right = Arrays.copyOfRange(array, mid, length);return merge(mergeSort(left), mergeSort(right));}private int[] merge(int[] left, int[] right) {int[] res = new int[left.length + right.length]; // 需要额外的内存空间int index = 0, i = 0, j = 0;while (i < left.length && j < right.length) {if (left[i] <= right[j]) {res[index] = left[i];i++;} else {res[index] = right[j];j++;}index++;}// 添加左边剩余元素while (i < left.length) {res[index] = left[i];i++;index++;}// 添加右边剩余元素while (j < right.length) {res[index] = right[j];j++;index++;}return res;}/*** 4、希尔排序(缩小增量排序)* 插入排序的优化版本,分组插入排序* <p>* 不稳定;平均时间复杂度:o(nLogn)* <p>* 速记:增加gap=length/2,在插入排序基础上外层while(gap>0)** @param array* @return*/public int[] shellSort(int[] array) {int length = array.length;if (length == 0) {return array;}int gap = length / 2;while (gap > 0) {for (int i = 0; i < length - gap; i++) {int insertNum = array[i + gap];int preIndex = i;while (preIndex >= 0 && insertNum < array[preIndex]) {array[preIndex + gap] = array[preIndex];preIndex = preIndex - gap;}array[preIndex + gap] = insertNum;}gap = gap / 2;}return array;}/*** 3、插入排序(while)* <p>* 从未排序数组中取出第一个数,从后往前扫描已排序数组,找到需要插入的下标。默认第一个数已排好序* <p>* 稳定; 平均时间复杂度:o(n^2)* <p>* 速记:外层for循环0~length-1(第一位数已排好序),记录i+1将要插入的数,记录i下标,内层while循环,i--,插入数小于当前数时,复制数到下一位(右边)** @param array* @return*/public int[] insertionSort(int[] array) {int length = array.length;if (length == 0) {return array;}for (int i = 0; i < length - 1; i++) {int insertNum = array[i + 1];int preIndex = i;while (preIndex >= 0 && insertNum < array[preIndex]) {array[preIndex + 1] = array[preIndex];preIndex--; // 从后往前扫描,到需要插入的位置后停下}array[preIndex + 1] = insertNum;}return array;}/*** 2、选择排序* <p>* 从未排序数组中挑选最小的数放在已排序的末尾。第i躺排序将第i小的数放在第i位上* 注:每趟保存最小数的下标,与第i位交换,不可直接赋值* <p>* 不稳定; 平均时间复杂度:o(n^2)* <p>* 速记:双重for循环,外层0~length,保存当前下标,内层i+1~length,记录最小数下标后交换** @param array* @return*/public int[] selectionSort(int[] array) {int length = array.length;if (length == 0) {return array;}for (int i = 0; i < length; i++) {int minIndex = i; // 找到最小数的下标,需要交换,不可直接赋值for (int j = i + 1; j < length; j++) {if (array[j] < array[minIndex]) {minIndex = j;}}int tmp = array[i];array[i] = array[minIndex];array[minIndex] = tmp;}return array;}/*** 1、冒泡排序* <p>* 注:第i趟排序将第i大的数放在倒数第i的位置上,所以后i位数无需再次比较* <p>* 稳定; 平均时间复杂度:o(n^2)* <p>* 速记:双重for循环,外层length,内层n-length - 1 - i** @param array* @return*/public int[] bubbleSort(int[] array) {int length = array.length;if (length == 0) {return array;}for (int i = 0; i < length; i++) {for (int j = 0; j < length - 1 - i; j++) {if (array[j] > array[j + 1]) {int tmp = array[j];array[j] = array[j + 1];array[j + 1] = tmp;}}}return array;}
}
【JAVA】经典排序算法,注释详细+可直接运行相关推荐
- Java经典排序算法:选择排序,动图演示排序过程
Java经典排序算法:选择排序,动图演示排序过程 示意动图: public class Main {public static void main(String[] args) {new Main() ...
- Java经典排序算法
提示:本文仅供自己学习 Java经典排序算法 一.排序算法概念及分类 1.排序概念 2.排序分类 二.十大排序算法 1.冒泡排序(BubbleSort) 2.选择排序(Selection sort) ...
- 我的Java开发学习之旅------gt;Java经典排序算法之希尔排序
一.希尔排序(Shell Sort) 希尔排序(Shell Sort)是一种插入排序算法,因D.L.Shell于1959年提出而得名. Shell排序又称作缩小增量排序. 二.希尔排序的基本思想 希尔 ...
- 我的Java开发学习之旅------Java经典排序算法之希尔排序
一.希尔排序(Shell Sort) 希尔排序(Shell Sort)是一种插入排序算法,因D.L.Shell于1959年提出而得名. Shell排序又称作缩小增量排序. 二.希尔排序的基本思想 希尔 ...
- Java经典排序算法的含义解析
想想已经和Java打了五六年的交道了,而越是时间越长,那些基本的东西就差不多都忘了差不多,今天碰巧看到很常见的三种Java算法,还是抽一点时间用自己的方式解释给自己听,然后彻底吸收一下,免得日后有人玩 ...
- 我的Java开发学习之旅------Java经典排序算法之二分插入排序
一.折半插入排序(二分插入排序) 将直接插入排序中寻找A[i]的插入位置的方法改为采用折半比较,即可得到折半插入排序算法.在处理A[i]时,A[0]--A[i-1]已经按关键码值排好序.所谓折半比较, ...
- C++实现桶排序——十大经典排序算法之九【GIF动画+完整代码+详细注释】
十大经典排序算法系列博客-->传送门 桶排序是计数排序的升级版.它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定.桶排序 (Bucket sort)的工作的原理:假设输入数据服从均 ...
- 十大经典排序算法详细总结 图形展示 代码示例
文章目录 十大经典排序算法详细总结 0.排序算法说明 1.冒泡排序(Bubble Sort) 2.选择排序(Selection Sort) 3.插入排序(Insertion Sort) 4.希尔排序( ...
- java 3 9 2 6数字排序_GitHub - JourWon/sort-algorithm: 史上最全经典排序算法总结(Java实现)...
史上最全经典排序算法总结(Java实现) 查找和排序算法是算法的入门知识,其经典思想可以用于很多算法当中.因为其实现代码较短,应用较常见.所以在面试中经常会问到排序算法及其相关的问题.但万变不离其宗, ...
- 终于,把十大经典排序算法汇总了!(Java实现版)
转载自 终于,把十大经典排序算法汇总了!(Java实现版) 最近几天在研究排序算法,看了很多博客,发现网上有的文章中对排序算法解释的并不是很透彻,而且有很多代码都是错误的,例如有的文章中在" ...
最新文章
- 关于Resin SSL支持的两个问题
- STM32 中JTAG 引脚作为普通IO口设置方法
- Mybatis入门---一对多、多对多
- java对象和json对象之间互相转换
- Linux环境下通过gstack命令查看进程的运行堆栈信息
- Swift观察者模式
- Apple Silicon配置二进制环境(一)
- c语言中输入输出基本格式
- 二手笔记本电脑电池测试软件,笔记本电池修复软件Battery Doubler V1.2.1免费已注册版...
- Spring Boot在使用Gradle build命令卡住不动了
- 惠普打印机 HP web 服务打不开
- FIR 滤波器参数意义
- windows下管理员用户与标准用户切换过程中的坑
- 新手程序员必备10大技能
- 悲催的体能测试,需要休整的身体~
- Graphql是什么
- 隔行换色并且鼠标指向行变色的表格
- 好妈妈胜过好老师 书摘
- 企业邮箱地址怎么写你知道吗?这样的邮箱地址更专业
- 【OpenCV】Chapter10.色彩转换与图像绘制