Java常用排序算法/程序员必须掌握的8大排序算法

article/2025/9/30 15:05:25

本文由网络资料整理而来,如有问题,欢迎指正!

 

参考链接:维基百科-排序算法

// 排序原始数据
private static final int[] NUMBERS =
{49, 38, 65, 97, 76, 13, 27, 78, 34, 12, 64, 5, 4, 62, 99, 98, 54, 56, 17, 18, 23, 34, 15, 35, 25, 53, 51};

 

插入排序 是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到{\displaystyle O(1)}的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。

 public static void insertSort(int[] array) {for (int i = 1; i < array.length; i++) {int temp = array[i];int j = i - 1;for (; j >= 0 && array[j] > temp; j--) {//将大于temp的值整体后移一个单位array[j + 1] = array[j];}array[j + 1] = temp;}System.out.println(Arrays.toString(array) + " insertSort");}

 

希尔排序  也称递减增量排序算法,是插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。

希尔排序是基于插入排序的以下两点性质而提出改进方法的:

  • 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率
  • 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位
public static void shellSort(int[] array) {int i;int j;int temp;int gap = 1;int len = array.length;while (gap < len / 3) { gap = gap * 3 + 1; }for (; gap > 0; gap /= 3) {for (i = gap; i < len; i++) {temp = array[i];for (j = i - gap; j >= 0 && array[j] > temp; j -= gap) {array[j + gap] = array[j];}array[j + gap] = temp;}}System.out.println(Arrays.toString(array) + " shellSort");
}

 

选择排序  是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

选择排序的主要优点与数据移动有关。如果某个元素位于正确的最终位置上,则它不会被移动。选择排序每次交换一对元素,它们当中至少有一个将被移到其最终位置上,因此对n个元素的表进行排序总共进行至多{\displaystyle n-1}次交换。在所有的完全依靠交换去移动元素的排序方法中,选择排序属于非常好的一种。

public static void selectSort(int[] array) {int position = 0;for (int i = 0; i < array.length; i++) {int j = i + 1;position = i;int temp = array[i];for (; j < array.length; j++) {if (array[j] < temp) {temp = array[j];position = j;}}array[position] = array[i];array[i] = temp;}System.out.println(Arrays.toString(array) + " selectSort");
}

 

堆排序  是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子节点的键值或索引总是小于(或者大于)它的父节点。

public static void heapSort(int[] array) {/**  第一步:将数组堆化*  beginIndex = 第一个非叶子节点。*  从第一个非叶子节点开始即可。无需从最后一个叶子节点开始。*  叶子节点可以看作已符合堆要求的节点,根节点就是它自己且自己以下值为最大。*/int len = array.length - 1;int beginIndex = (len - 1) >> 1;for (int i = beginIndex; i >= 0; i--) {maxHeapify(i, len, array);}/** 第二步:对堆化数据排序* 每次都是移出最顶层的根节点A[0],与最尾部节点位置调换,同时遍历长度 - 1。* 然后从新整理被换到根节点的末尾元素,使其符合堆的特性。* 直至未排序的堆长度为 0。*/for (int i = len; i > 0; i--) {swap(0, i, array);maxHeapify(0, i - 1, array);}System.out.println(Arrays.toString(array) + " heapSort");
}
private static void swap(int i, int j, int[] arr) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;
}
/*** 调整索引为 index 处的数据,使其符合堆的特性。** @param index 需要堆化处理的数据的索引* @param len   未排序的堆(数组)的长度*/
private static void maxHeapify(int index, int len, int[] arr) {int li = (index << 1) + 1; // 左子节点索引int ri = li + 1;           // 右子节点索引int cMax = li;             // 子节点值最大索引,默认左子节点。if (li > len) {return;       // 左子节点索引超出计算范围,直接返回。}if (ri <= len && arr[ri] > arr[li]) // 先判断左右子节点,哪个较大。{ cMax = ri; }if (arr[cMax] > arr[index]) {swap(cMax, index, arr);      // 如果父节点被子节点调换,maxHeapify(cMax, len, arr);  // 则需要继续判断换下后的父节点是否符合堆的特性。}
}

 

冒泡排序  是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

public static void bubbleSort(int[] array) {int temp = 0;for (int i = 0; i < array.length - 1; i++) {for (int j = 0; j < array.length - 1 - i; j++) {if (array[j] > array[j + 1]) {temp = array[j];array[j] = array[j + 1];array[j + 1] = temp;}}}System.out.println(Arrays.toString(array) + " bubbleSort");
}

 

快速排序  又称划分交换排序,简称快排,一种排序算法,最早由东尼·霍尔提出。在平均状况下,排序n个项目要{\displaystyle \ O(n\log n)}(大O符号)次比较。在最坏状况下则需要{\displaystyle O(n^{2})}次比较,但这种状况并不常见。事实上,快速排序{\displaystyle \Theta (n\log n)}通常明显比其他算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地达成。

public static void quickSort(int[] array) {_quickSort(array, 0, array.length - 1);System.out.println(Arrays.toString(array) + " quickSort");
}private static int getMiddle(int[] list, int low, int high) {int tmp = list[low];    //数组的第一个作为中轴while (low < high) {while (low < high && list[high] >= tmp) {high--;}list[low] = list[high];   //比中轴小的记录移到低端while (low < high && list[low] <= tmp) {low++;}list[high] = list[low];   //比中轴大的记录移到高端}list[low] = tmp;              //中轴记录到尾return low;                  //返回中轴的位置
}private static void _quickSort(int[] list, int low, int high) {if (low < high) {int middle = getMiddle(list, low, high);  //将list数组进行一分为二_quickSort(list, low, middle - 1);      //对低字表进行递归排序_quickSort(list, middle + 1, high);      //对高字表进行递归排序}
}

 

归并排序  是创建在归并操作上的一种有效的排序算法,效率为{\displaystyle O(n\log n)}(大O符号)。1945年由约翰·冯·诺伊曼首次提出。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用,且各层分治递归可以同时进行。

public static void mergingSort(int[] array) {sort(array, 0, array.length - 1);System.out.println(Arrays.toString(array) + " mergingSort");
}private static void sort(int[] data, int left, int right) {if (left < right) {//找出中间索引int center = (left + right) / 2;//对左边数组进行递归sort(data, left, center);//对右边数组进行递归sort(data, center + 1, right);//合并merge(data, left, center, right);}
}private static void merge(int[] data, int left, int center, int right) {int[] tmpArr = new int[data.length];int mid = center + 1;//third记录中间数组的索引int third = left;int tmp = left;while (left <= center && mid <= right) {//从两个数组中取出最小的放入中间数组if (data[left] <= data[mid]) {tmpArr[third++] = data[left++];} else {tmpArr[third++] = data[mid++];}}//剩余部分依次放入中间数组while (mid <= right) {tmpArr[third++] = data[mid++];}while (left <= center) {tmpArr[third++] = data[left++];}//将中间数组中的内容复制回原数组while (tmp <= right) {data[tmp] = tmpArr[tmp++];}
}

 

基数排序  是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。

public static void radixSort(int[] array) {//首先确定排序的趟数;int max = array[0];for (int i = 1; i < array.length; i++) {if (array[i] > max) {max = array[i];}}int time = 0;//判断位数;while (max > 0) {max /= 10;time++;}//建立10个队列;ArrayList<ArrayList<Integer>> queue = new ArrayList<>();for (int i = 0; i < 10; i++) {ArrayList<Integer> queue1 = new ArrayList<>();queue.add(queue1);}//进行time次分配和收集;for (int i = 0; i < time; i++) {//分配数组元素;for (int anArray : array) {//得到数字的第time+1位数;int x = anArray % (int)Math.pow(10, i + 1) / (int)Math.pow(10, i);ArrayList<Integer> queue2 = queue.get(x);queue2.add(anArray);queue.set(x, queue2);}int count = 0;//元素计数器;//收集队列元素;for (int k = 0; k < 10; k++) {while (queue.get(k).size() > 0) {ArrayList<Integer> queue3 = queue.get(k);array[count] = queue3.get(0);queue3.remove(0);count++;}}}System.out.println(Arrays.toString(array) + " radixSort");
}

 

结果

 

 


http://chatgpt.dhexx.cn/article/3C99Cov5.shtml

相关文章

排序算法:选择排序

1. 什么是选择排序&#xff1f;&#xff08;摘抄自百度百科&#xff09; 选择排序&#xff08;Selection sort&#xff09;是一种简单直观的排序算法。 它的工作原理是&#xff1a; 第一次从待排序的数据元素中选出最小&#xff08;或最大&#xff09;的一个元素&#xff0c…

排序算法——选择排序

目录 &#x1f43e;基本介绍 &#x1f31e;算法思想&#xff1a; &#x1f330;实例&#xff1a; ⛅思路分析&#xff1a; &#x1f308;总结&#xff1a; &#x1f6f4;代码实现: &#x1f6f9;算法性能分析 &#x1f355;时间复杂度 &#x1f367;空间复杂度 &…

基本算法-选择排序

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 前言 本文介绍一种经典排序算法——选择排序&#xff0c;是入门级的排序算法之一。以下是本篇文章正文内容&#xff0c;包括算法简…

程序员八大排序算法之直接选择排序算法(java版)

一&#xff0c;选择排序算法思路&#xff1a;每趟选择序列的最小值/最大值&#xff0c;采取贪心选择策略。 二&#xff0c;选择排序算法有两种&#xff1a;1.直接选择排序 2.堆排序&#xff08;基于二叉树&#xff09;。 &#xff08;这里讲解直接选择排序&#xff09; 三&a…

排序算法--选择排序(Java实现)

选择排序概念 选择排序&#xff08;Selection sort&#xff09;是一种简单直观的排序算法。它的工作原理是&#xff1a;第一次从待排序的数据元素中选出最小&#xff08;或最大&#xff09;的一个元素&#xff0c;存放在序列的起始位置&#xff0c;然后再从剩余的未排序元素中寻…

java之选择排序

基本介绍 选择排序同样属于内部排序法&#xff0c;是从欲排序的数据中&#xff0c;按指定的规则选出某一元素&#xff0c;再按规定交换位置达到排序的目的。 排序思想 选择排序是一种简单的排序方法。它的基本思想是&#xff1a;第一次从arr[0]~arr[n-1]中选取最小值&#xf…

java选择排序(含选择排序代码)

目录 一&#xff1a;选择排序的思想 ​二&#xff1a;选择排序的代码 三&#xff1a;结果 一&#xff1a;选择排序的思想 选择排序是一种简单直观的排序算法。它的工作原理是&#xff1a;第一次从待排序的数据元素中选出最小&#xff08;或最大&#xff09;的一个元素&…

选择排序算法

选择排序&#xff08;Selection Sort&#xff09;是一种简单直观的排序算法。它的工作原理是&#xff1a;第一次从待排序的数据元素中选出最小&#xff08;或最大&#xff09;的一个元素&#xff0c;存放在序列的起始位置&#xff0c;然后再从剩余的未排序元素中寻找到最小&…

Java——常见的几种排序算法

一、冒泡排序 每次冒泡过程都是从数列的第一个元素开始&#xff0c;然后依次和剩余的元素进行比较, 跟列队一样, 从左到右两两相邻的元素比大小, 高的就和低的换一下位置. 最后最高(值最大)的肯定就排到后面了. 但是这只是把最高的排到后面了, 还得找出第二高的, 于是又从第一…

Java实现选择排序

Java实现选择排序 选择排序原理为&#xff1a;随机确定一个标志位&#xff08;一般为第一个数字&#xff09;作为最小数&#xff0c;然后向后遍历&#xff0c;找到比标志位更小的数便与标志位互换位置并更新最小数&#xff0c;实现步骤为&#xff1a; 将数组的第一个数字设置…

【算法】选择排序法

一、介绍 1.选择排序法是将序列分为两段&#xff0c;有序前列和无序后列&#xff0c;每次查找无序后列中最大元素&#xff0c;将其插入到有序前列的最末尾处&#xff0c;直至无序后列最后一个元素&#xff0c;最终排序后的序列为降序序列 2.适用于包括数组和向量在内的序列 …

选择排序的两种算法(Java代码实现)

目录 选择排序&#xff1a; 基本思想&#xff1a; 1&#xff1a;简单选择排序&#xff1a; 基本思想&#xff1a; 过程&#xff1a; 2&#xff1a;堆排序&#xff1a; 基本思想&#xff1a; 过程&#xff1a; 选择排序&#xff1a; 基本思想&#xff1a; 每一趟从待排序…

Java选择排序

1. 选择排序 选择排序是一种简单直观的排序算法&#xff0c;其基本原理是每一次从待排序的数组里找到最小值&#xff08;最大值&#xff09;的下标&#xff0c;然后将最小值&#xff08;最大值&#xff09;跟待排序数组的第一个进行交换&#xff0c;然后再从剩余的未排序元素中…

数据仓库理论知识

数据仓库 1.1 数仓基础知识 1.1.1. 为什么要有数据仓库 通常数据仓库的数据来自各个业务应用系统。业务系统中的数据形式多种多样&#xff0c;可能是 Oracle、MySQL、SQL Server 等关系数据库里的结构化数据&#xff0c;可能是文本、CSV 等平面文件或 Word、Excel 文档中的数…

数据仓库技术中的MPP

数据仓库世界里面的massively parallel processing 大概定义&#xff1a; MPP 是将任务并行的分散到多个服务器和节点上&#xff0c;在每个节点上计算完成后&#xff0c;将各自部分的结果汇总在一起得到最终的结果。       首先MPP 必须消除手工切分数据的工作量。 这是…

数据挖掘和数据仓库之间的区别

数据挖掘和仓储对于任何希望在全球或国家层面获得认可的组织来说都是必不可少的两个过程。这两种技术都有助于防止数据欺诈并提高管理统计数据和排名。数据挖掘用于依靠在数据仓库阶段收集的数据来检测重要模式。 数据挖掘和数据仓库都被视为数据分析的一部分。但它们以不同的方…

数据仓库ETL技术探究

ETL概述 在构建商业智能系统的时候&#xff0c;如何正确有效地将分散在各个不同数据源中的信息整合到系统中成为了整个系统成败的关键&#xff0c;直接影响到系统的运行效率和最终结果。 ETL正是解决这一问题的有力工具。 ETL是指把数据从数据源装人数据仓库的过程&#xff0c…

数据仓库与数据挖掘知识点梳理

数据仓库与数据挖掘知识点梳理 一&#xff1a;数据挖掘 1&#xff1a;什么是数据挖掘 数据挖掘是从大量的数据中挖掘出隐含的、未知的、用户可能感兴趣的和对决策有潜在价值的知识和规则。 ----简单的说&#xff0c;数据挖掘就是从大量的数据中发现有用信息的过程 数据的丰富…

Greenplum 实时数据仓库实践(1)——数据仓库简介

目录 1.1 什么是数据仓库 1.2 操作型系统与分析型系统 1.2.1 操作型系统 1.2.2 分析型系统 1.2.3 操作型系统和分析型系统对比 1.3 抽取-转换-装载 1.3.1 数据抽取 1.3.2 数据转换 1.3.3 数据装载 1.3.4 开发ETL系统的方法 1.4 数据仓库架构 1.4.1 基本架构 …