当前位置: 首页 > news >正文

常见的排序算法总结

        

目录

插入排序

直接插入排序

希尔排序

选择排序

选择排序

堆排序

交换排序

冒泡排序

快速排序

归并排序

排序算法总结


排序即使一串记录按照其中某个或某些关键字的大小,递增或递减的排列起来的操作。排序这块所说的稳定性就是指,在排序前相同的数据的顺序在排序后依然保持这个顺序,如果排序前后这个顺序没有发生改变,就说明这个排序算法是稳定的,反之不稳定。

        常见的排序算法可以分为:插入排序(直接插入排序、希尔排序)、选择排序(选择排序、堆排序)、交换排序(冒牌排序、快速排序)、归并排序。

插入排序

直接插入排序

        直接插入排序即将待排记录按其关键码的值逐个插入到已经排好序的有序序列中,直到所有的记录插入完为止。插入排序的空间复杂度为O(1),平均时间复杂度为O(n^2),最坏时间复杂度是O(n^2),也就是待排序列为逆序的情况,最好的时间复杂度是O(n),也就是待排序列为要排的顺序时,它是稳定的排序算法。

public class InsertSort {private static void insertSort(int[] nums) {if (nums == null || nums.length == 0) {return;}for (int i = 1; i < nums.length; i++) { // 待排序列int j = i - 1;int tmp = nums[i];for (; j >= 0; j--) { // 有序序列if (tmp < nums[j]) {nums[j + 1] = nums[j];} else {break;}}nums[j + 1] = tmp;}}public static void main(String[] args) {int[] nums = {6,5,4,4,3,1,2,10,8};insertSort(nums);for (int num : nums) {System.out.print(num + " ");}}
}

希尔排序

        希尔排序是在直接插入排序基础上做的进一步优化。它是将待排序列按照指定距离分为若干个组,然后对每个组分别进行直接插入排序,当指定距离为1时,排序结束。

        此处这个指定距离gap的取法有很多种,我们按照gap = n / 2这种方式来进行取值,每一轮结束后gap /= 2,直到gap == 1为止。

        希尔排序的空间复杂度为O(1),是不稳定的排序算法,其时间复杂度最好的情况下是O(n),最坏的情况是O(n^2),平均时间复杂度是O(n^1.3)。

public class ShellSort {public static void shellSort(int[] nums) {if (nums == null || nums.length == 0) {return;}int gap = nums.length / 2;while (gap >= 1) {shell(nums, gap);gap /= 2;}}public static void shell(int[] nums, int gap) {for (int i = gap; i < nums.length; i++) { // 待排序列int j = i - gap;int tmp = nums[i];for (; j >= 0; j -= gap) { // 有序序列if (nums[j] > tmp) {nums[j + gap] = nums[j];} else {break;}}nums[j + gap] = tmp;}}public static void main(String[] args) {int[] nums = {6,5,4,4,3,1,2,10,8};shellSort(nums);for (int num : nums) {System.out.print(num + " ");}}
}

选择排序

选择排序

        选择排序(以升序为例)即每次从待排序列中选则最小的一个待排元素放在序列起始位置,直到所有待排序元素排完为止。选择排序的平均时间复杂度、最好时间复杂度、最坏时间复杂度都是O(n^2),空间复杂度为O(1),是不稳定的排序算法。

public class SelectSort {public static void selectSort(int[] nums) {if (nums == null || nums.length == 0) {return;}for (int i = 0; i < nums.length; i++) {int minIndex = i; // 记录最小值的下标for (int j = i; j < nums.length; j++) {if (nums[minIndex] > nums[j]) {minIndex = j;}}int tmp = nums[minIndex];nums[minIndex] = nums[i];nums[i] = tmp;}}public static void main(String[] args) {int[] nums = {6,5,4,4,3,1,2,10,8};selectSort(nums);for (int num : nums) {System.out.print(num + " ");}}
}

堆排序

        堆排序是指利用堆这种数据结构所设计的一种排序算法,它是选择排序的一种,它是通过堆来选择数据的。当要排升序的时候建立大根堆,排降序时建立小根堆。

        以排升序为例:

        1、首先我们要建立一个大根堆(如果要排降序,建立小根堆)

        2、将堆顶元素与堆最后一个元素进行交换,使末尾元素最大;

        3、继续调整堆,再将堆顶元素与堆最后一个元素进行互换,得到第二大元素;

        4、重复2和3操作,直到end==0,结束排序。

        堆排序是不稳定的排序算法,其空间复杂度为O(1),时间复杂度为O(nlog2n)。

public class HeapSort {private static void heapSort(int[] nums) {if (nums == null || nums.length == 0) {return;}// 1、创建大根堆createHeap(nums);// 堆排序int end = nums.length - 1;while (end > 0) {swap(nums, 0, end);shiftDown(nums, 0, end);end--;}}private static void createHeap(int[] nums) {for (int parent = (nums.length - 2) / 2; parent >= 0; parent--) { // 确保从最后一个非叶子结点开始向下调整shiftDown(nums, parent, nums.length);}}private static void shiftDown(int[] nums, int parent, int len) {int child = parent * 2 + 1; // 通常指向的是当前结点的左孩子while (child < len) {if (child + 1 < len && nums[child] < nums[child + 1]) { // 确保child指向的是两个节点中最大的那个child++;}if (nums[parent] < nums[child]) {swap(nums, parent, child);parent = child;child = 2 * parent + 1;} else {break;}}}private static void swap(int[] nums, int left, int right) {int tmp = nums[left];nums[left] = nums[right];nums[right] = tmp;}public static void main(String[] args) {int[] nums = {6,5,4,4,3,1,2,10,8,9,9,9,9};heapSort(nums);for (int num : nums) {System.out.print(num + " ");}}
}

交换排序

冒泡排序

        冒泡排序是一种简单的排序算法,它重复的遍历数组,每次比较两个元素,按照规定的排序规则将其排序,当数组已经有序时,排序结束.冒泡排序无论数组是否有序都会遍历一遍数组。其平均时间复杂度为O(n^2),最好时间复杂度为O(n),最坏时间复杂度为O(n^2),空间复杂度为O(1),是稳定的排序算法。

public class BubbleSort {public static void bubbleSort(int[] nums) {if (nums == null || nums.length == 0) {return;}for (int i = 0; i < nums.length; i++) {int flag = 0;for (int j = 0; j < nums.length - i - 1; j++) {if (nums[j] > nums[j + 1]) {int tmp = nums[j];nums[j] = nums[j + 1];nums[j + 1] = tmp;flag = 1;}}if (flag == 0) {break;}}}public static void main(String[] args) {int[] nums = {6,5,4,4,3,1,2,10,8};bubbleSort(nums);for (int num : nums) {System.out.print(num + " ");}}
}

快速排序

        任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直至所有元素都排列在相应位置上为止。快速排序是不稳定的排序算法,其空间复杂度为O(log2n),其平均时间复杂度为O(log2n),

public class QuickSort {public static void quickSort(int[] nums, int start, int end) {if (start >= end) {return;}int pivot = partition(nums, start, end);quickSort(nums, start, pivot - 1);quickSort(nums, pivot + 1, end);}private static int partition(int[] nums, int left, int right) {int tmp = nums[left];while (left < right) {// 从右边找到第一个比它小的值while (left < right && nums[right] >= tmp) {right--;}nums[left] = nums[right];// 从左边找第一个大于它的值while (left < right && nums[left] <= tmp) {left++;}nums[right] = nums[left];}nums[left] = tmp;return left;}public static void main(String[] args) {int[] nums = {6,5,4,4,3,1,2,10,8};quickSort(nums, 0, nums.length - 1);for (int num : nums) {System.out.print(num + " ");}}
}

归并排序

        归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个经典应用。将已有序的子序列合并,得到完全有序的序列;先使每个子序列有序,再使子序列段间有序。归并排序的时间复杂度为O(nlog2n),空间复杂度是O(n),是稳定的排序算法。

public class MergeSort {private static void mergeSort(int[] nums, int left, int right) {if (left >= right) {return;}int mid = (left + right) / 2;mergeSort(nums, left, mid);mergeSort(nums, mid + 1, right);merge(nums, left, right, mid);}private static void merge(int[] nums, int left, int right, int mid) {int[] tmp = new int[right - left + 1];int s1 = left;int e1 = mid;int s2 = mid + 1;int e2 = right;int k = 0;while (s1 <= e1 && s2 <= e2) { // 两个归并段都有数据if (nums[s1] <= nums[s2]) { // <= 确保了它是稳定的排序算法tmp[k++] = nums[s1++];} else {tmp[k++] = nums[s2++];}}while (s1 <= e1) {tmp[k++] = nums[s1++];}while (s2 <= e2) {tmp[k++] = nums[s2++];}for (int i = 0; i < k; i++) {nums[i + left] = tmp[i];}}public static void main(String[] args) {int[] nums = {6,5,4,4,3,1,2,10,8};mergeSort(nums, 0, nums.length - 1);for (int num : nums) {System.out.print(num + " ");}}
}

排序算法总结

        稳定性:上述的七大排序算法中,其中归并排序、插入排序、冒泡排序是稳定的排序算法;选择排序、希尔排序、堆排序、快速排序是不稳定的排序算法。

        空间复杂度:冒泡排序、插入排序、希尔排序、选择排序、堆排序的空间复杂度是O(1),快速排序的空间复杂度是O(nlog2n),归并排序的空间复杂度为O(n)。

        时间复杂度:以平均时间复杂度来看,冒泡排序、插入排序、选择排序的平均时间复杂度是O(n^2),希尔排序的平均时间复杂度是O(n^1.3),归并排序、快速排序、堆排序的平均时间复杂度是O(nlog2n)。


文章转载自:

http://F8J1rj6q.kchwr.cn
http://S75TCiYy.kchwr.cn
http://aD6B1FHF.kchwr.cn
http://HTZgh3oh.kchwr.cn
http://QFX3WAmN.kchwr.cn
http://QX38ictg.kchwr.cn
http://gyCM1tAG.kchwr.cn
http://zVhbCZyy.kchwr.cn
http://jfljDTwg.kchwr.cn
http://Q7quvzYH.kchwr.cn
http://EIIb5kaf.kchwr.cn
http://RnqlZXwu.kchwr.cn
http://PpRo3H5p.kchwr.cn
http://LgtkX5Lr.kchwr.cn
http://svAcKXaJ.kchwr.cn
http://eBp7Ds5T.kchwr.cn
http://JYB9HgXx.kchwr.cn
http://ZU894EtA.kchwr.cn
http://VGEwB927.kchwr.cn
http://E9FdepCE.kchwr.cn
http://OlBv2sRZ.kchwr.cn
http://PafF12vp.kchwr.cn
http://KtPOiqoW.kchwr.cn
http://04KISmRV.kchwr.cn
http://mf2cA5ri.kchwr.cn
http://HrK5RPhh.kchwr.cn
http://FC0yHaY4.kchwr.cn
http://Aov3ForW.kchwr.cn
http://X5Fybh5q.kchwr.cn
http://Y1MSA2Wa.kchwr.cn
http://www.dtcms.com/a/374874.html

相关文章:

  • [优化算法]神经网络结构搜索(一)
  • php 使用html 生成pdf word wkhtmltopdf 系列2
  • 大数据毕业设计选题推荐-基于大数据的海洋塑料污染数据分析与可视化系统-Hadoop-Spark-数据可视化-BigData
  • 【计算机网络 | 第11篇】宽带接入技术及其发展历程
  • 探索Java并发编程--从基础到高级实践技巧
  • Made in Green环保健康产品认证怎么做?
  • yum list 和 repoquery的区别
  • 解决HTML/JS开发中的常见问题与实用资源
  • Angular 面试题及详细答案
  • AI与AR融合:重塑石化与能源巡检的未来
  • 增强现实光学系统_FDTD_zemax_speos_学习(1)
  • 开学季干货——知识梳理与经验分享
  • Alex Codes团队并入OpenAI Codex:苹果生态或迎来AI编程新篇章
  • The learning process of Decision Tree Model|决策树模型学习过程
  • 六、与学习相关的技巧(下)
  • 《低功耗音频:重塑听觉体验与物联网边界的蓝牙革命》
  • 20250909的学习笔记
  • 金融量化指标--5Sortino索提诺比率
  • 消息三剑客华山论剑:Kafka vs RabbitMQ vs RocketMQ
  • 均值/方差/标注查介绍
  • 深入解析Guava RateLimiter限流机制
  • 开发中使用——鸿蒙子页面跳转到指定Tab页面
  • HarmonyOS实现快递APP自动识别地址
  • AJAX入门-URL
  • 【C++】18. 红⿊树实现
  • 基于Java Spring Boot的云原生TodoList Demo 项目,验证云原生核心特性
  • 记录一次rk3568硬解码时cpu占用率高的问题
  • Electron 跨平台兼容性:处理 OS 差异
  • Docker 学习笔记(五):网络与存储核心原理及实战应用
  • Who Wants To Be King: 1靶场渗透