• 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);  
    }  
  • 相关阅读:
    ubuntu系统安装初始化脚本
    21_多线程
    20_IO
    19_异常
    18_集合
    17_内部类和常用类
    16_接口
    15_abstract,static,final
    14_面向对象
    13_数组
  • 原文地址:https://www.cnblogs.com/daocaorenblog/p/5300066.html
Copyright © 2020-2023  润新知