zoukankan      html  css  js  c++  java
  • heap

    STL heap以vector为底层容器,从1开始存,2i为左子节点,即是个二叉堆,是个大根堆。

    优先队列(priority queue)允许用户以任何次序将任何元素插入容器,但取出时要从优先权最大的元素开始取。二叉大根堆具有这样的特性,因此作为优先队列的底层机制。

    能不能用list作为优先队列底层机制?

    list作为优先队列底层机制可以实现元素插入的常数时间,但是要找到list的最值,却要对list做线性扫描。我们可以先对元素排序,这样,找到最值以及元素删除为常数时间,但是元素的插入又是线性时间。

    能不能用二叉搜索树作为优先队列底层机制? 

    用二叉搜索树元素插入和最值取得都可以在O(logn)内完成,但是这样小题大做:第一,二叉搜索树的输入需要足够的随机性;第二,二叉搜索树的实现不容易。

    push_heap(first,last):(当数组中已经放入了一个新的元素并且这个元素位于容器最尾端,数组之前是有序的)用来将尾端元素调整至有序的位置

    pop_heap(first,last):将最大元素放置最尾端,然后调整数组使有序(最大元素要调用pop_back()进行删除,现在还未删,数组之前是有序的

    sort_heap(first,last):对所有元素进行整体升序排列(数组之前是满足二叉堆的规则的,所以实际实现是用pop_heap每次排列后最大元素归位)

    make_heap(first,last):对无序的元素进行排序使得它满足二叉堆的规则

    push_heap中的核心算法如下:

    template <class RandomAccessIterator, class Distance, class T, class Compare>  
    void __push_heap(RandomAccessIterator first, Distance holeIndex,  
                     Distance topIndex, T value, Compare comp)  
    {  
      Distance parent = (holeIndex - 1) / 2;  
      while (holeIndex > topIndex && comp(*(first + parent), value)) {  
        *(first + holeIndex) = *(first + parent);  
        holeIndex = parent;  
        parent = (holeIndex - 1) / 2;  
      }  
      *(first + holeIndex) = value;  
    }  

    pop_heap以及make_heap的核心算法是一样的,如下:

    template <class RandomAccessIterator, class Distance, class T>  
    void __adjust_heap(RandomAccessIterator first, Distance holeIndex,  
                       Distance len, T value)  
    {  
      Distance topIndex = holeIndex;  
      Distance secondChild = 2 * holeIndex + 2;     // 弹出元素的有子孩  
      
      // 调整heap元素位置  
      while (secondChild < len) {  
        // 选择两个子孩中较大的进行操作, 使用secondChild表示其偏移  
        if (*(first + secondChild) < *(first + (secondChild - 1)))  
          secondChild--;  
      
        // 将较大元素向上填充, 并将整体偏移向下调整, 继续调整  
        *(first + holeIndex) = *(first + secondChild);  
        holeIndex = secondChild;  
        secondChild = 2 * (secondChild + 1);  
      }  
      
      if (secondChild == len) {  
        *(first + holeIndex) = *(first + (secondChild - 1));  
        holeIndex = secondChild - 1;  
      }  
      
      __push_heap(first, holeIndex, topIndex, value);  
    }  
  • 相关阅读:
    安卓基础值之Intent
    输入值/表单提交参数过滤有效防止sql注入的方法
    一致性hash
    linux授权某个用户对某个目录有读写的权限
    mysql分区功能详细介绍,以及实例
    SVN分支与主干
    solr查询
    mysql-proxy做客户端连接转发【外网访问内网mysql】
    liunx 下安装 php_screw 扩展 以及报错处理
    邮件发送
  • 原文地址:https://www.cnblogs.com/daocaorenblog/p/5300066.html
Copyright © 2011-2022 走看看