Go语言学习笔记【15】 排序算法之堆排序、桶排序、基数排序

【声明】

非完全原创,部分内容来自于学习其他人的理论。如果有侵权,请联系我,可以立即删除掉。

一、堆排序

1、方法和复杂度

1.1、核心思想

  • 利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点
  • 根据这个特点,先将待排序的序列构造成一个小顶堆,则堆顶就是序列中最小的元素
  • 取出堆顶元素,用最后一个元素填充堆顶,然后重新构建小顶堆
  • 重复上面过程,取出来的元素就是一个从小到大的有序序列

1.2、主要方法

1.2.1、筛选法

(1)构建小顶堆:按照完全二叉树的规则,将元素依次填充到树上的结点;然后根据下往上,从右往左得顺序,根据小顶堆的规则比较子结点和父结点进行调整,直到整棵树都满足小顶堆的要求
(2)取出堆顶元素,剩余元素重新构建小顶堆
(3)重复(2),直到序列只剩下一个元素,则取出来的序列就是有序序列

1.2.2、插入法

主要区别在于初始创建堆的过程。筛选法是先用元素依次填满二叉树,然后根据规则进行调整;而插入法:

  • 假设二叉树是空的,先将第一个元素作为根结点
  • 从后面取一个待插入的结点,将被插入元素与其父节点进行比较,若大于父节点,则与父节点交换交换后继续向上检查,直到根结点
  • 重复上一个步骤,直到所有元素插入到完全二叉树中并调整成小顶堆

1.3、特点及构建堆的分析

(1)特点:
  • 对于小顶堆有:arr[i] <= arr[2i + 1] && arr[i] <= arr[2i + 2]
  • 对于大顶堆有:arr[i] >= arr[2i + 1] && arr[i] >= arr[2i + 2]
(2)分析

注意:数组最后一个元素是一个叶子结点,因此以此为突破口,可以查找其父结点。
当完全二叉树除了叶子结点之外,其他结点均有左右子结点时,树的结点总个数为奇数,以此分析:

  • 若数组长度为偶数,则最后元素是左叶子结点,得:2*dad + 1 == len(arr)-1 ==> dad = len(arr)/2 -1
  • 若数组长度为奇数,则最后元素是右叶子结点,得:2*dad + 2 == len(arr)-1 ==> dad = [len(arr)-1] /2 - 1

因此,最后一个元素的父结点索引是len(arr)/2-1,而该结点也是最后一个非叶子结点

1.3、稳定性

该算法不能保证相等元素的相对顺序,属于非稳定排序。原因是,父结点和子节点进行交换时,可能会将后面的元素交换到前面去,从而破坏稳定性

举例:假如数组{5, 7, 6, 4, 3, 4}。则小顶堆构建时,第一次交换就破坏了稳定性。
构建小顶堆

1.4、时间复杂度

具体分析见:堆排序算法描述及时间复杂度分析

1.4.1、初始化堆的时间复杂度

最好情况:当按照顺序排列出的完全二叉树完全满足堆的规则时,父结点只需要和左右子结点比较大小,不需要进行元素交换,其时间复杂度为 O ( N ) O(N) O(N)
最坏情况:当每次调整堆进行检查时,父节点每次都需要和子结点交换位置,且子节点也需要不停往下检查换位,直到叶子结点。设当前结点的深度为k,则该层的结点最多有 2 k − 1 2^{k-1} 2k1。设堆的高度为 h = l o g 2 N h = log_2N h=log2N,则当前结点最坏情况需要移动到最后一层,则移动的次数为h - k。而每一层需要和左、右节点比较,因此每层需要比较2次。那么最坏情况下的时间复杂度为:

T [ N ] = T[N] = T[N]= ∑ k = 1 h − 1 2 k − 1 ∗ 2 ∗ ( h − k ) \sum_{k=1}^{h-1}2^{k-1}*2*(h-k) k=1h12k12(hk)= ∑ k = 1 h − 1 2 k ( h − k ) \sum_{k=1}^{h-1}2^k(h-k) k=1h12k(hk)
= ( h − 1 ) 2 1 + ( h − 2 ) 2 2 + ( h − 3 ) 2 3 + . . + 2 h − 1 ∗ 1 = (h-1)2^1+(h-2)2^2+(h-3)2^3+..+2^{h-1}*1 =(h1)21+(h2)22+(h3)23+..+2h11
由于 2 T [ N ] = ( h − 1 ) 2 2 + ( h − 2 ) 2 3 + ( h − 3 ) 2 4 + . . + 2 h ∗ 1 2T[N]=(h-1)2^2+(h-2)2^3+(h-3)2^4+..+2^h*1 2T[N]=(h1)22+(h2)23+(h3)24+..+2h1, 因此
T [ N ] = 2 0 + 2 1 + 2 2 + 2 3 + . . + 2 h − 2 ∗ h − 1 T[N]=2^0+2^1+2^2+2^3+..+2^h-2*h-1 T[N]=2

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值