1. 二叉堆:
    1. 右数组建立的堆,在任意位置i上,左节点为2i,右节点为2i+1,父亲在i/2上, 数组的0位置为空的前提,否则是2i+1,2i+2
    2. 小顶堆堆中的每一个节点小于他的儿子,根节点没有父亲。大顶堆每一个节点大于他儿子节点
    3.  
    4. 插入要求:尾部插入,然后调整堆,直到这个堆顺序稳定
      1. 调整的过程使得小元素不断往上冒,这种策略称为上滤
      2. 由于堆是使用数组,所以当容量饱和时候,需要进行扩展,就像ArrayList进行1.5倍扩展
      3. 先不急着插入尾部,用该值与他爹比较先,寻找到最佳位置插入,减少交换可提高效率
      4. 注意到达根节点的边界,计数器记得++;
    5. 删除操作:
      1. 锁定第一个值和数组最后一个;由于删除使得计算器减少一个,第一个元素置空;
      2. 然后将最后一个继续从根向下调整堆结构;寻找可放进去的位置这个策略叫做下滤
      3. 避免频繁的交换,采用:
        1. 定义变量temp存储最后一个元素,且放在第一个位置
        2. 定义循环,找出根的儿子节点最小值在做还是右,再将这个最小值和根比较
          1. 如果根小,那么就停值循环
          2. 如果根是个大值,那么将小的儿子替换掉父亲,
          3. 然后儿子那个方向循环,也就是,那个儿子做根
  2. 小顶堆的最小值在根节点,最大值在所有叶子节点之中(接近一半的元素)
  3. 构建堆:
    1. 寻找最后的一个非叶子节点,也就是长度的一半开始
    2. 通过交换保持父亲节点拥有最小值,而且还需要下滤避免子节点的儿子中有比子节点更小的
    3. 直到节点到达根部
  4. 优先队列的应用
    1. 选择问题:
      1. 寻找第k大的元素
        1. 先排序再寻找
        2. 维持k大小的集合,建立成k大小堆结构,当插入新值时,只需和堆顶比较,判断是否替换堆顶,替换后需要下滤调整堆结构
        3. 类似快排的算法,通过比较舍弃,不断靠近k-1位置;
        4. 创建堆后,删除k-1次堆顶后,堆顶元素就是要寻找的值
  5. d-堆:d个子树的堆,是二叉堆的一种推广,在实践中4-堆胜过二叉堆,但是难合并(merge)
  6. 左式堆:非理想中的平衡,实际趋势非常不平衡
    1. 零路径长(npl):节点X儿子的最短路径,只有一个儿子就或没有儿子0;两个儿子就1;如果null就-1
    2. 无法使用数组表示,因为不平衡,所有高级支合并的数据结构都是使用链式储存
    3. 性质:对于堆中的每一个节点,左儿子的npl至少和右儿子相等或大于
    4. 左式堆趋向加深左路径,(在实际上更便于合并操作)
    5. 定理:在右路径上有r个节点的左式树必然至少有2^r-1个节点
    6. 左式堆是递归威力的完美实例
    7. 每个结点中需要有一个指示npl的项
    8. 左式堆操作:
      1. 基本操作是合并(merge),插入只是合并的一个特殊情形 。合并之后也是个左式堆;如果插入在右边,那么需要左右子树交换
      2. 删除:除去根节点得到两个堆,再将两个堆合并
  7. 斜堆:是左式堆的自调节形式(是一种代表缺少平衡原则的数据结构)
    1. 斜堆是具有堆排序的二叉树,但不存在对树结构的限制
    2. 不保留npl
    3. 基本操作还是合并
    4. 相对于左式堆的合并,斜堆不需要判断是否满足左式堆而进行交换操作
    5. 除了右路径上最后节点外,所有节点都将他们的儿子进行交换这种交换
  8. 二项队列
    1. 指出一种简单的想法如何能够用来达到好的时间界
    2. 堆序的树的集合,也就是森林
    3. 每一棵堆序树都有约束的形式:二项树
    4. 每一个高度至多存在一棵二项树
    5. 高度为0的数是单节点,而高度为k是把高度为k-1的树接到高度为k-1上
    6. 二项树操作
      1. 最小元可以通过搜索所有树的根来找出
      2. 合并:将同深度的两两合并
      3. 插入就是与单节点树合并
      4. 删除最小:把最小元的那棵树的根节点删除,儿子们成为各个独立的树,再和其他合并
  9. 标准库中优先队列 PriorityQueue
 
 
 
posted @ 2020-07-12 23:43  浪波激泥  阅读(122)  评论(0编辑  收藏  举报