• Jerry银银
    2018-11-26
    ## 第一题:

    使用数组存储表示完全二叉树时,从数组下标为1开始存储数据,数组下标为i的节点,左子节点为2i, 右子节点为2i + 1. 这个结论很重要(可以用数学归纳法证明),将此结论记为『原理1』,以下证明会用到这个原理。

    为什么,对于完全二叉树来说,下标从n/2 + 1 到 n的节点都是叶子节点? 使用反证法证明即可:

    如果下标为n/2 + 1的节点不是叶子节点,即它存在子节点,按照『原理1』,它的左子节点为:2(n/2 + 1) = n + 2,大家明显可以看出,这个数字已经大于n + 1,超出了实现完全二叉树所用数组的大小(数组下标从1开始记录数据,对于n个节点来说,数组大小是n + 1),左子节点都已经超出了数组容量,更何况右子节点。以此类推,很容易得出:下标大于n/2 + 1的节点肯定都是也叶子节点了,故而得出结论:对于完全二叉树来说,下标从n/2 + 1 到 n的节点都是叶子节点

    备注下:用数组存储表示完全二叉树时,也可以从下标为0开始,只是这样做的话,计算左子节点时,会多一次加法运算

    --------------------------------------------------------
    ## 第二题:

    堆的应用除了堆排以外,还有如下一些应用:
    1. 从大数量级数据中筛选出top n 条数据; 比如:从几十亿条订单日志中筛选出金额靠前的1000条数据
    2. 在一些场景中,会根据不同优先级来处理网络请求,此时也可以用到优先队列(用堆实现的数据结构);比如:网络框架Volley就用了Java中PriorityBlockingQueue,当然它是线程安全的
    3. 可以用堆来实现多路归并,从而实现有序,leetcode上也有相关的一题:Merge K Sorted Lists

    暂时只能想到以上三种常见的应用场景,其它的,希望老师补充!
    展开
     12
     267
  • Jessie
    2018-12-13
    强烈建议,在进入课程的左侧,做一个目录,这样就不用每次都从最新的滑到最下面了。例如:目前是学到了第35课,已进入课堂,就是35课,假如我想看第一课,就得使劲滑。如果学到100课,那得滑老半天……所以强烈建议给左侧添加一个目录。可以连接到每一节课。!!!
     3
     136
  • WhoAmWe
    2018-11-26
    应用:
    1.topK
    2.流里面的中值
    3.流里面的中位数

    作者回复: 👍

     2
     53
  • 大冯宇宙
    2018-11-27
    不知道有没有人很容易看懂原理思路,就是不愿意看代码
     6
     47
  • 无心拾贝
    2018-11-26
    这TM估计是我唯一看的懂的数据结构与算法吧。 谢谢老师!
    
     34
  • insist
    2018-11-26
    这种数据结构堆和java内存模型中的堆内存有什么关系呢?

    作者回复: 完全没关系的。

    
     28
  • 猫头鹰爱拿铁
    2018-11-26
    思考题1:堆是完全二叉树,求最后的非叶子节点即是求最大的叶子节点的父节点。最大的叶子节点下标为n,他的父节点为n/2,这是最后一个非叶子节点,所以n/2+1到n都是叶子节点。
    思考题2:堆排序的应用-topk问题,例如求数据频率最高的k个数,建立k个数的最小顶堆,然后剩余数据和堆顶比较,如果比堆顶大则替换堆顶并重新调整最小顶堆。
     4
     28
  • 1024
    2019-02-26
    思考题1证明
    结论:对于完全二叉树来说,下标从(n/2)+1到n都是叶子节点
    证明:
    假设堆有n个节点
    假设满二叉树有h层 则满二叉树的总节点数 2^0+2^1...+2^(h-2)+2^(h-1)=(2^h)-1> n n为h层完全二叉树节点数
    堆为完全二叉树,相同高度,完全二叉树总结点数小于满二叉树节点数,即n<(2^h)-1, 即(2^h)>n+1 -----①
    完全二叉树1到h-1层节点的数量总和: 2^0+2^1...+2^(h-2)=(2^(h-1))-1=(2^h)/2 -1 -----②
    如果数组的第0位也存储数据,由②可知,完全二叉树的第h层开始的节点的下标为i=(2^h)/2 -1,由①,i>((n+1)/2)-1=(n/2)+1
    结论1:如果数组的第0位也存储数据,完全二叉树的节点下标至少开始于(n/2)+1
    如果数组的第0位不存储数据,则由②可知,完全二叉树的第h层开始的节点的下标为j=(2^h)/2,由①,j>(n+1)/2=(n/2)+2
    结论2:如果数组的第0位不存储数据,完全二叉树的节点下标至少开始于(n/2)+2
    综上,堆(完全二叉树)的叶子节点的下标范围从(n/2)+1到n-1或从(n/2)+2到n,也即堆的叶子节点下标从(n/2)+1到n
    欢迎指正
    --不为别的,就为成为更合格的自己
    展开

    作者回复: 👍

     5
     15
  • Smallfly
    2018-11-26
    堆应该可以用于实现优先级队列。
    
     15
  • 鲍勃
    2018-11-30
    linux内核内存中的堆和这个有关系吗?

    作者回复: 没关系 完全是两个东西

    
     8
  • yaya
    2018-11-26
    最后一个结点的父节点是n/2.这是最后一个非叶子结点所以,叶子结点是n/2+1到n。
    优先队列的实现用的就是堆
    
     6
  • Brandon
    2018-12-14
    排序队------时间复杂度
    堆满足两条:1、完全二叉树(可以很方便的使用数组存储),2、父节点大于或小于子节点-----
    插入元素-先放入队尾,再进行堆化(heapify)
    删除元素-从最后取一个元素放到删除元素位置,从上往下调整

    快排比堆排性能好的原因有二:1、堆排序数据访问的方式有没有快速排序友好;
    2、对于同样的数据,在排序的过程中堆排序算法的交换次数多于快速排序
    展开
    
     5
  • .
    2018-12-14
    "对堆顶节点进行堆化,会依次访问数组下标是 1,2,4,8"。这里图画错了吧,数组下标2 (20)和数组下标3(21)的位置应该是弄反了。如果按原图对堆顶元素堆化的话顺序应该是1,3,6不应该是1,2,4,8

    作者回复: 嗯嗯 多谢指正

    
     5
  • 李建轰
    2018-11-30
    老师你好~
    heapify方法好像有点问题?
    假如第一个非叶子节点是5,左叶子节点是7,右叶子节点是6
    然后入heapify方法的这段代码
    ```
    while (true) {
        int maxPos = i;
        if (i*2 <= n && a[i] < a[i*2]) maxPos = i*2;
        if (i*2+1 <= n && a[i] < a[i*2+1]) maxPos = i*2+1
        if (maxPos == i) break;
        swap(a, i, maxPos);
        i = maxPos;
    }
    ```
    就会变成第一个非叶子节点是6,左叶子节点是7,右叶子节点是5,因为swap只会执行一次。
    我觉得swap方法在前面两个if里面都得有,并且第二个if必须用if,不能用else if。
    斗胆提问,请老师答疑~
    展开
     2
     5
  • 『LHCY』
    2019-02-18
    刚才面试遇到了这道题,不过没想起来
     2
     4
  • 若星
    2018-12-12
    删除堆顶元素的代码第二行return -1。。
    
     4
  • qinggeouye
    2018-12-23
    重点:父节点和它的左右子节点比较大小关系,并交换。
    对于某个节点:
    从上往下堆化,时间复杂度和高度成正比
    从下往上堆化,时间复杂度和深度成正比
    
     3
  • 博予liutxer
    2018-12-09
    堆排序和快速排序相比实际开发中不如后者性能好,那堆排序在哪些场景比较有优势呢?

    作者回复: 时间复杂度比较稳定 有些排序函数会使用这种排序算法

    
     3
  • Vinegar.
    2018-11-26
    Java 中的 PriorityQueue 就是基于堆的数据结构的
    
     3
  • fumeck.com🍋🌴s...
    2018-11-26
    我们将下标从 n/2 到 1的节点,依次进行从上到下的堆化操作
    不是由下往上吗老师,最后一个才轮到根节点阿

    作者回复: 哈哈 弄混淆了 堆化是有两种方式:从上到下和从下到上,前面讲到了。我这里说的从下到上,是指的堆化操作本身。

    
     3
我们在线,来聊聊吧