【heap】是算法不是容器哦

前面是一些小Tips和关键点,以及代码里不好理解的点,后面是源码,重要的函数全部都写了满满的注释嘿嘿嘿!
为什么是这种形式呢,因为看书的时候就是讲解源码的,于是顺着读代码的时候就加了注释。

heap

  • heap不归属于STL容器组件,是扮演priority queue(允许任何次序推入容器内,但取出一定是从优先权最高的元素开始取)的助手。binary max heap就适合做它的底层机制。关键:内部排序!

  • binary heap:完全二叉树的形态(好处:可用array存储所有节点,左右子节点为2i和2i+1,父节点i/2,称为隐式表述法)。故heap是一个array和一组heap算法,为了动态改变大小,用vector代替array。

  • heap分为max-heap和min-heap,STL默认前者。不提供遍历,故没有迭代器。

  • push_heap:上溯程序在这里插入图片描述

  • pop_heap:去掉根节点,下溯。注意:pop取走根节点的操作实际上是将其移至底部容器vector的最后一个元素,为了维持二叉树,需要将下一层的最右节点拿掉,补充到上面的空缺。在这里插入图片描述

  • 调用方法:(以算法形式呈现)vector< int> a; make_heap(a.begin(),a.end());
    a.push_back(7); push_heap(a.begin(),a.end());
    pop_heap(a.begin(),a.end());
    sort_heap(a.begin(),a.end());在这里插入图片描述

#ifndef __SGI_STL_INTERNAL_HEAP_H
#define __SGI_STL_INTERNAL_HEAP_H

__STL_BEGIN_NAMESPACE

#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
#pragma set woff 1209
#endif

//这组push_back()不允许指定“大小比较标准”
//first是头结点存放的下标(并不默认就是0)
template <class RandomAccessIterator, class Distance, class T>
void __push_heap(RandomAccessIterator first, Distance holeIndex,
                 Distance topIndex, T value) {
   
  Distance parent = (holeIndex - 1) / 2; // 找出父节点
  while (holeIndex > topIndex && *(first + parent) < value) {
   
  // 当尚未到达顶端且父节点小于新值,fisrt是起始点
    *(first + holeIndex) = *(first + parent);//令洞值为父值
    holeIndex = parent;//调整洞号,向上提升至父节点
    parent = (holeIndex - 1) / 2;//新洞的父节点
  }    //持续至顶端或满足heap次序特性为止
  *(first + holeIndex) = value;//令洞值为新值,完成插入操作
}

template <class RandomAccessIterator, class Distance, class T>
inline void __push_heap_aux(RandomAccessIterator first,
                            RandomAccessIterator last, Distance*, T*) {
   
  __push_heap(first, Distance((last - first) - 1), Distance(0), 
              T(*(last - 1)));
   //容器的最尾端为第一个洞号
}

template <class RandomAccessIterator>
inline void push_heap(RandomAccessIterator first, RandomAccessIterator last) {
   
  //注意此函数被调用时新元素应该已经置于底部容器的最尾端
  __push_heap_aux(first, last, distance_type(first), value_type(first))
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值