【面试八股总结】排序算法(二)

参考资料 :阿秀

一、堆排序

堆排序基本思想是先把数组构造成一个大顶堆(父亲节点大于其子节点) ,然后把堆顶(数组最大值,数组第一个元素)和数组最后一个元素交换,这样就把最大值放到了数组最后边。把数组长度n-1,再进行构造堆把剩余的第二大值放到堆顶,输出堆顶(放到剩余未排序数组最后面)。依次类推,直至数组排序完成。

大顶(小顶)堆

① 是一个完全二叉树

设二叉树的深度为h,除最后一层h层之外,其余各层的结点数都达到了最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。

② 所有父节点的值都要大于(或小于)子节点的值

如何构建堆?

使用数组表示二叉树,数组下标就是节点编号。由于是完全二叉树,可以简单的推断出:

若当前节点下标为i,则其父节点下标为(i - 1)/2 子节点下标分别为:2i+1 和 2i+2。

如何确保所有父节点的值都大于子节点呢?

从完全二叉树的倒数第二层也就是h-1层开始,从下往上进行遍历,遍历每个非叶子节点,若当前节点的值小于子节点值,则将当前节点值与子节点交换,直到遍历到根节点。

注意:调整每个节点为最大值后,需要递归调整交换的子节点是否也满足为最大值。

如何使用堆完成排序呢?

堆构建完成后,每次将堆顶取出,将最后一个叶子节点作为堆顶,然后从堆顶出发,递归调整整个堆,保证父节点的值都要大于子节点的值,调整完成后,将新的堆顶取出,循环该操作直至排序完成。

推荐一个视频,up主讲的很清楚:堆排序(heapsort)_哔哩哔哩_bilibili

二、计数排序

计数排序的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。计数排序统计小于等于该元素值的元素的个数i,于是该元素就放在目标数组的索引i位(i≥0)。

  • 计数排序基于一个假设,待排序数列的所有数均为整数,且出现在(0,k)的区间之内。
  • 如果 k(待排数组的最大值) 过大则会引起较大的空间复杂度,一般是用来排序 0 到 100 之间的数字的最好的算法,但是它不适合按字母顺序排序人名。
  • 计数排序不是比较排序,排序的速度快于任何比较排序算法。

算法思想

  1. 找出待排序的数组中最大和最小的元素;
  2. 统计数组中每个值为 i 的元素出现的次数,存入数组 C 的第 i 项;
  3. 对所有的计数累加(从 C 中的第一个元素开始,每一项和前一项相加);
  4. 向填充目标数组:将每个元素 i 放在新数组的第 C[i] 项,每放一个元素就将 C[i] 减去 1;

三、桶排序

桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于映射函数的确定。为了使桶排序更加高效,我们需要做到这两点:

  1. 在额外空间充足的情况下,尽量增大桶的数量
  2. 使用的映射函数能够将输入的 N 个数据均匀的分配到 K 个桶中

同时,对于桶中元素的排序,选择何种比较排序算法对于性能的影响至关重要。

什么时候最快?

当输入的数据可以均匀的分配到每一个桶中。

什么时候最慢?

当输入的数据被分配到了同一个桶中。

算法思想

  1. 设置一个定量的数组当作空桶子。
  2. 寻访序列,并且把项目一个一个放到对应的桶子去。
  3. 对每个不是空的桶子进行排序。
  4. 从不是空的桶子里把项目再放回原来的序列中。

四、基数排序

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

算法思想

  1. 取得数组中的最大数,并取得位数;
  2. arr为原始数组,从最低位开始取每个位组成radix数组;
  3. 对radix进行计数排序(利用计数排序适用于小范围数的特点);
相关推荐
bitbitDown6 分钟前
从零打造一个 Vite 脚手架工具:比你想象的简单多了
前端·javascript·面试
沐怡旸13 分钟前
【穿越Effective C++】条款16:成对使用new和delete时要采用相同形式——内存管理的精确匹配原则
c++·面试
异步的告白1 小时前
C语言-数据结构-1-动态数组
c语言·数据结构·c++
Miraitowa_cheems3 小时前
LeetCode算法日记 - Day 98: 分割回文串 II
数据结构·算法·leetcode·深度优先·动态规划
立志成为大牛的小牛3 小时前
数据结构——三十九、顺序查找(王道408)
数据结构·学习·程序人生·考研·算法
矢心3 小时前
setTimeout 和 setInterval:看似简单,但你不知道的使用误区
前端·javascript·面试
2301_807997383 小时前
代码随想录-day30
数据结构·c++·算法·leetcode
ゞ 正在缓冲99%…4 小时前
leetcode1771.由子序列构造的最长回文串长度
数据结构·算法·leetcode
拉不动的猪4 小时前
关于scoped样式隔离原理和失效情况&&常见样式隔离方案
前端·javascript·面试
Mr.H01275 小时前
快速排序的常见构思
数据结构·算法