常见排序算法时间复杂度、空间复杂度、稳定性总结

转载:https://blog.csdn.net/yushiyi6453/article/details/76407640

排序算法分类

这里写图片描述

排序算法比较表格

排序算法平均时间复杂度最坏时间复杂度空间复杂度是否稳定
冒泡排序O(n2)O(n2)O(1)
选择排序O(n2)O(n2)O(1)不是
直接插入排序O(n2)O(n2)O(1)
归并排序O(nlogn)O(nlogn)O(n)
快速排序O(nlogn)O(n2)O(logn)不是
堆排序O(nlogn)O(nlogn)O(1)不是
希尔排序O(nlogn)O(ns)O(1)不是
计数排序O(n+k)O(n+k)O(n+k)
基数排序O(N∗M)O(N∗M)O(N∗M)O(M)

注:

1 归并排序可以通过手摇算法将空间复杂度降到O(1),但是时间复杂度会提高。

2 基数排序时间复杂度为O(N*M),其中N为数据个数,M为数据位数。

辅助记忆

  • 时间复杂度记忆- 
    • 冒泡、选择、直接 排序需要两个for循环,每次只关注一个元素,平均时间复杂度为O(n2)(一遍找元素O(n)O(n),一遍找位置O(n)O(n))
    • 快速、归并、希尔、堆基于二分思想,log以2为底,平均时间复杂度为O(nlogn)(一遍找元素O(n),一遍找位置O(logn))
  • 稳定性记忆-“快希选堆”(快牺牲稳定性) 
    • 排序算法的稳定性:排序前后相同元素的相对位置不变,则称排序算法是稳定的;否则排序算法是不稳定的。

原理理解

1 冒泡排序

1.1 过程

冒泡排序从小到大排序:一开始交换的区间为0~N-1,将第1个数和第2个数进行比较,前面大于后面,交换两个数,否则不交换。再比较第2个数和第三个数,前面大于后面,交换两个数否则不交换。依次进行,最大的数会放在数组最后的位置。然后将范围变为0~N-2,数组第二大的数会放在数组倒数第二的位置。依次进行整个交换过程,最后范围只剩一个数时数组即为有序。

1.2 动图

1.3核心代码

2 选择排序

2.1 过程

选择排序从小到大排序:一开始从0~n-1区间上选择一个最小值,将其放在位置0上,然后在1~n-1范围上选取最小值放在位置1上。重复过程直到剩下最后一个元素,数组即为有序。

2.2 动图


2.3核心代码

3 插入排序

3.1 过程

插入排序从小到大排序:首先位置1上的数和位置0上的数进行比较,如果位置1上的数大于位置0上的数,将位置0上的数向后移一位,将1插入到0位置,否则不处理。位置k上的数和之前的数依次进行比较,如果位置K上的数更大,将之前的数向后移位,最后将位置k上的数插入不满足条件点,反之不处理。

3.2 动图

 

3.3核心代码

4 归并排序

4.1 过程

归并排序从小到大排序:首先让数组中的每一个数单独成为长度为1的区间,然后两两一组有序合并,得到长度为2的有序区间,依次进行,直到合成整个区间。

4.2 动图

 

4.3核心代码

·递归实现

·迭代实现

5 快速排序

5.1 过程

快速排序从小到大排序:在数组中随机选一个数(默认数组首个元素),数组中小于等于此数的放在左边,大于此数的放在右边,再对数组两边递归调用快速排序,重复这个过程。

5.2 动图

 

5.3核心代码

6 堆排序

6.1 过程

堆排序从小到大排序:首先将数组元素建成大小为n的大顶堆,堆顶(数组第一个元素)是所有元素中的最大值,将堆顶元素和数组最后一个元素进行交换,再将除了最后一个数的n-1个元素建立成大顶堆,再将最大元素和数组倒数第二个元素进行交换,重复直至堆大小减为1。

  • 注:完全二叉树 
    假设二叉树深度为n,除了第n层外,n-1层节点都有两个孩子,第n层节点连续从左到右。如下图 
    这里写图片描述

  • 注:大顶堆 
    大顶堆是具有以下性质的完全二叉树:每个节点的值都大于或等于其左右孩子节点的值。 
    即,根节点是堆中最大的值,按照层序遍历给节点从1开始编号,则节点之间满足如下关系: 
    这里写图片描述 (1<=i<=n/2)

6.2 动图

 
 

6.3 核心代码(函数)

这里写图片描述
注意!!!数组从1开始,1~n。

7 希尔排序

7.1 过程

希尔排序是插入排序改良的算法,希尔排序步长从大到小调整,第一次循环后面元素逐个和前面元素按间隔步长进行比较并交换,直至步长为1,步长选择是关键。

7.2 动图

这里写图片描述 

7.3 核心程序(函数)

8 桶排序(基数排序和基数排序的思想)

8.1 过程

桶排序是计数排序的变种,把计数排序中相邻的m个”小桶”放到一个”大桶”中,在分完桶后,对每个桶进行排序(一般用快排),然后合并成最后的结果。

8.2 图解

8.3 核心程序

9 计数排序

9.1 过程

算法的步骤如下: 
- 找出待排序的数组中最大和最小的元素 
- 统计数组中每个值为i的元素出现的次数,存入数组C的第i项 
- 对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加) 
- 反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1

9.2 图解

这里写图片描述

9.3核心代码

10 基数排序

10.1 过程

基数排序是基于数据位数的一种排序算法。 
它有两种算法 
①LSD–Least Significant Digit first 从低位(个位)向高位排。 
②MSD– Most Significant Digit first 从高位向低位(个位)排。 
时间复杂度O(N*最大位数)。 
空间复杂度O(N)。

10.2 图解

这里写图片描述 
对a[n]按照个位0~9进行桶排序: 
这里写图片描述 
对b[n]进行累加得到c[n],用于b[n]中重复元素计数 
!!!b[n]中的元素为temp中的位置!!!跳跃的用++补上: 
这里写图片描述 
temp数组为排序后的数组,写回a[n]。temp为按顺序倒出桶中的数据(联合b[n],c[n],a[n]得到),重复元素按顺序输出: 
这里写图片描述

 

10.3核心代码

 

  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值