heap概述
heap并不归属于STL容器组件,它是幕后英雄,扮演了priority queue的助手;
priority queue允许用户以任意顺序将元素推入容器内,但是取出时,是按优先级最高的元素开始取。针对priority queue要求的特性,最直观的做法,有两种:
1:插入后,保持底层queue的排序状态,此时插入的时间复杂度是O(n);取数据可在常数时间内将元素取出
2:插入还是放在容器的末尾,插入的时间复杂度尾O(1);取数据时,需要遍历数组,而后取出最大的那个元素;时间复杂度为O(n);
此外为了能够获取O(logN)时间复杂度性能的插入和获取性能,可能会想到用二分查找树的方式(红黑树);事实上如果采用红黑树的做法,也能实现该功能,只是再实现复杂度和存储容量上都会有一定程度上的提升;本文采用了binary heap的方式进行实现;
所谓binary heap就是一种complete binary tree(完全二叉树),也就是整颗binary tree除了最底层的叶子节点之外,是填满的,且最底层的叶子节点由左至右不得存在空隙。如下图所示
因为完全二叉树节点紧凑的特性;我们可以采用array来存储所有节点;其中i标识父节点的索引,则其左右子几点的索引分别为2*i 及2*i+1;如此一颗完全二叉树可以通过array进行表示,同时我们称这种表示法为隐式表述法(implicit representation)。
如此分析之后,我们需要的工具,可以采用一个array和一组heap算法(用于插入元素、删除元素、取极值,将某一整组数据排列成一个heap)。array的缺点是无法动态改变大小,而heap却需要这项功能,因此,以vector代替array。
根据元素排列方式,heap可分为max-heap和min-heap两种,前者每个节点的键值(key)都大于或等于其子节点键值,后者的每个节点键值(key)都小于或等于其子节点键值。因此,max-heap的最大值在根节点,并总是位于底层array或vector的起始处(front);min-heap
的最小值在根节点,亦总是位于底层array或vector的起始处(front)。STL提供的max-heap,以下描述的算法都是指max-heap。
heap 算法
push_heap算法
push_heap,将元素加入heap中
heap初始状态如下:
此时需要将新的节点加入heap中,假设加入新的节点的key为50.
此时待加入的节点位于heap的末尾,亦即tree最底层叶子节点的最右端
加入节点后,这颗