算法小结——排序算法总结

本文总结了常见的排序算法,包括直接插入排序、希尔排序、简单选择排序、堆排序、冒泡排序、快速排序和归并排序。通过对这些算法的详细解释和时间复杂度分析,帮助读者深入理解排序算法的原理和应用。
摘要由CSDN通过智能技术生成

1. 总览

  • 排序
    • 插入排序类
      • 直接插入排序 O ( n 2 ) O(n^2) O(n2)
      • 希尔排序 O ( n l o g n ) − O ( n 2 ) O(nlogn) - O(n^2) O(nlogn)O(n2)
    • 选择排序类
      • 简单选择排序 O ( n 2 ) O(n^2) O(n2)
      • 堆排序 O ( n l o g n ) O(nlogn) O(nlogn)
    • 交换排序类
      • 冒泡排序 O ( n 2 ) O(n^2) O(n2)
      • 快速排序 O ( n l o g n ) O(nlogn) O(nlogn)
    • 归并排序类
      • 归并排序 O ( n l o g n ) O(nlogn) O(nlogn)

2. 直接插入排序

插入排序的基本方法是:每一步将一个待排序的元素,按其排序码的大小,插入到前面已经排好序的一组元素的适当位置上去,直到元素全部插入为止。

  • 当插入第i(i >= 1)时,前面的V[0],V[1],……,V[i-1]已经排好序。这时,用V[i]的排序码与V[i-1],V[i-2],…的排序码顺序进行比较,找到插入位置即将V[i]插入,原来位置上的元素向后顺移。

在这里插入图片描述

3. 希尔排序

直接插入排序在小规模或是基本有序的数据集中效率较高。希尔排序就是对数据进行预处理,在预处理的基础上进行插入排序以提高效率。

  • 首先它把较大的数据集合分割成若干个小组(逻辑上分组),然后对每一个小组分别进行插入排序,此时,插入排序所作用的数据量比较小(每一个小组),插入的效率比较高。

在这里插入图片描述

  • 经过排序得到部分有序的数组:[1, 2, 4, 3, 5, 7, 8, 6]。

  • 然后将增量缩小为之前的一半,在此重复之前的分组排序过程。

  • 经过排序得到部分有序的数组:[1, 2, 4, 3, 5, 6, 8, 7]
  • 然后将增量缩小为之前的一半,此时为1,则所有数据在一组中,再进行插入排序得到最后的排序结果。此时数据基本有序,插入排序效率高。

4. 简单选择排序

每次选择一个最大(小)的,直到所有元素都被输出。

5. 堆排序

堆是满足下列性质的完全二叉树:

  • 每个节点都大于或是等于其左右孩子节点的值,称为大顶堆
  • 每个节点都小于或是等于其左右孩子节点的值,称为小顶堆[外链图片转存失败,源站可能有防盗链机制,

在这里插入图片描述

同时,我们对堆中的结点按层进行编号,将这种逻辑结构映射到数组中就是下面这个样子

堆排序基本思想及步骤

堆排序的基本思想是:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了

步骤一 构造初始堆。将给定无序序列构造成一个大顶堆(一般升序采用大顶堆,降序采用小顶堆)。

  1. 假设给定无序序列结构如下
  1. 此时我们从最后一个非叶子结点开始(叶结点自然不用调整,第一个非叶子结点 arr.length/2-1=5/2-1=1,也就是下面的6结点),从左至右,从下至上进行调整。

在这里插入图片描述

  1. 找到第二个非叶节点4,由于[4,9,8]中9元素最大,4和9交换。

在这里插入图片描述

  1. 这时,交换导致了子根[4,5,6]结构混乱,继续调整,[4,5,6]中6最大,交换4和6。

在这里插入图片描述

此时,我们就将一个无需序列构造成了一个大顶堆。

步骤二 将堆顶元素与末尾元素进行交换,使末尾元素最大。然后继续调整堆,再将堆顶元素与末尾元素交换,得到第二大元素。如此反复进行交换、重建、交换。

  1. 将堆顶元素9和末尾元素4进行交换

在这里插入图片描述

  1. 重新调整结构,使其继续满足堆定义

在这里插入图片描述

  1. 再将堆顶元素8与末尾元素5进行交换,得到第二大元素8.

在这里插入图片描述

  1. 后续过程,继续进行调整,交换,如此反复进行,最终使得整个序列有序

再简单总结下堆排序的基本思路:

a.将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;

b.将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;

c.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。

6. 冒泡排序

算法思路:

  1. 比较相邻的元素。如果第一个比第二个大(小),就交换他们两个。
  2. 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大(最小)的数。
  3. 针对所有的元素重复以上的步骤,除了最后一个(已经为最大/最小)。持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

7. 快速排序

设置low和high两个指针(low=0,high=size-1)并将数组内的一个值设置为pivot,将数据分为大于pivot和小于pivot的两个部分,并对pivot作用分界点的左右两部分数组递归的调用这个过程,最终得到有序数组。

实现原理

  1. 设置两个变量 low、high,排序开始时:low=0,high=size-1。

  2. 整个数组找基准正确位置,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面

    2.1. 默认数组的第一个数为基准数据,赋值给key,即key=array[low]。

    2.2. 因为默认数组的第一个数为基准,所以从后面开始向前搜索(high–),找到第一个小于key的array[high],就将 array[high] 赋给 array[low],即 array[low] = array[high]。(循环条件是 array[high] >= key;结束时 array[high] < key)

    2.3. 此时从前面开始向后搜索(low++),找到第一个大于key的array[low],就将 array[low] 赋给 array[high],即 array[high] = array[low]。(循环条件是 array[low] <= key;结束时 array[low] > key)

    2.4. 循环 2-3 步骤,直到 low=high,该位置就是基准位置。

    2.5. 把基准数据赋给当前位置。

  3. 第一趟找到的基准位置,作为下一趟的分界点。

  4. 递归调用(recursive)分界点前和分界点后的子数组排序,重复2.2、2.3、2.4的步骤。

  5. 最终就会得到排序好的数组。

在这里插入图片描述

8. 归并排序

归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题(divide)成一些小的问题然后递归求解,而**治(conquer)**的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。

分而治之

在这里插入图片描述

可以看到这种结构很像一棵完全二叉树,本文的归并排序我们采用递归去实现(也可采用迭代的方式去实现)。阶段可以理解为就是递归拆分子序列的过程,递归深度为log2n。

合并相邻有序子序列

再来看看阶段,我们需要将两个已经有序的子序列合并成一个有序序列,比如上图中的最后一次合并,要将[4,5,7,8]和[1,2,3,6]两个已经有序的子序列,合并为最终序列[1,2,3,4,5,6,7,8],来看下实现步骤。
在这里插入图片描述

在这里插入图片描述

9. 时间复杂度总结

在这里插入图片描述

参考资料:

https://baijiahao.baidu.com/s?id=1653077762711837226&wfr=spider&for=pc

https://blog.csdn.net/eric_sunah/article/details/103080731

https://blog.csdn.net/sun7545526/article/details/85165742

https://blog.csdn.net/eric_sunah/article/details/103081878

ttps://blog.csdn.net/eric_sunah/article/details/103080731

https://blog.csdn.net/sun7545526/article/details/85165742

https://blog.csdn.net/eric_sunah/article/details/103081878

https://blog.csdn.net/eric_sunah/article/details/103082607

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值