第6章 堆排序

原地算法

6.1 堆

二叉堆:存储上使用数组,逻辑上是二叉树,近似于完全二叉树。
存储顺序是树的广度优先遍历顺序。

第i个节点的父节点存储在 i/2 中。(数学归纳法可证)

第i个节点的左孩子存储在 2i 中。

第i个节点的父节点存储在 2i+1 中。

最大堆性质:父节点元素大于等于子节点元素。(根节点除外,其没有父节点)

最大堆性质:父节点元素小于等于子节点元素。(根节点除外,其没有父节点)

节点的高度:该结点到叶结点最长简单路径上边的数目。
堆的高度就是根结点的高度。

n个结点的完全二叉树的高度是$\Theta(lgn)$

练习:

等比数列求和公式:

Sn=anqa1q1

6.1-1 最少:

1+2+...+2h1+1=2h12121+1=2h

最多:

1+2+...+2h1+2h=2h2121=2h+11

6.1-2 设 n=2h+k,0k2h1,kZ 易得。

6.1-6 不是,7的位置有问题。

6.1-7 完全二叉树中叶结点的数目为 n2

推导如下:

设叶子节点个数为n0,度为1的节点个数为n1,度为2的节点个数为n2。
1. n0+n1+n2=n
2. 1+n1+2*n2=n

消去n2,得:
n0=(n+1-n1)/2
由完全二叉树性质得,n1为1或者0.若树高为h,则除最下层结点外,结点总数为$2^h-1$,为奇数。

  • 故n为奇数时,n1为0

    n0=(n+1)/2

  • 故n为偶数时,n1为1

    n0=n/2

由此,完全二叉树中叶结点的数目为 n2

由叶结点下标计算完全二叉树中叶结点的数目:

n(n/2+1)+1=nn/2=n/2

得证。

6.2 维护堆的性质

每个孩子的子树至多为 2n/3
最坏情况分析。
设矮的子树高为h,高子树为h+1。
矮子树结点数 2h1 ,高子树节点数 2h+11 ,又 n=2h+11+2h1 ,故可认为高子树结点数为 2n/3

练习

6.2-4 注意完全二叉树的性质,这个结点应该是叶子结点。

6.3 建堆

注意这个算法实际上是线性时间的。

练习

6.3-3 对高度为0或者h的结论易证,一般情况数学归纳法可证。

6.4 堆排序算法

排序完成是升序。

练习

6.4-4 升序在建堆的过程中会破坏这个序,故其需要 O(n)+(n1)lgn ;降序本身能看成是一个最大堆,maxHeapify不会发生递归,则 O(n)

6.5 优先队列

示例是最大优先队列。
支持操作:

  • 插入
  • 返回最大值(heapMax)
  • 返回最大值并将其从堆中移除(heapExtractMax)
  • 将元素x的关键字增加到k(heapIncreaseKey),维持堆的性质,也就是下层结点值会变大。

练习

6.5-8 把这个数和数组尾部的数互换,调整这个子树
6.5-9
1. 从k个链表中取出每个链表的第一个元素,组成一个大小为k的数组arr,然后将数组arr转换为最小堆,那么arr[0]就为最小元素了
2. 取出arr[0],将其放到新的链表中,然后将arr[0]元素在原链表中的下一个元素补到arr[0]处,即arr[0].next,如果 arr[0].next为空,即它所在的链表的元素已经取完了,那么将堆的最后一个元素补到arr[0]处,堆的大小自动减一,循环n-k次即可。

思考题

6-3 young氏矩阵
这个形式的矩阵似乎在校招笔试中出现多次。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值