首先说说数据结构概念——堆(Heap),其实也没什么大不了,简单地说就是一种有序队列而已,普通的队列是先入先出,而二叉堆是:最小先出。 数组
这不是很简单么?若是这个队列是用数组实现的话那用打擂台的方式从头至尾找一遍,把最小的拿出来不就好了?行啊,但是出队的操做是很频繁的,而每次都得打一遍擂台,那就低效了,打擂台的时间复杂度为Ο(n),那如何不用从头至尾fetch一遍就出队呢?二叉堆能比较好地解决这个问题,不过以前先介绍一些概念。 数据结构
彻底树(Complete Tree):从下图中看出,在第n层深度被填满以前,不会开始填第n+1层深度,还有必定是从左往右填满。
fetch
再来一棵彻底三叉树:
spa
这样有什么好处呢?好处就是能方便地把指针省略掉,用一个简单的数组来表示一棵树,如图:
指针
那么下面介绍二叉堆:二叉堆是一种彻底二叉树,其任意子树的左右节点(若是有的话)的键值必定比根节点大,上图其实就是一个二叉堆。 队列
你必定发觉了,最小的一个元素就是数组第一个元素,那么二叉堆这种有序队列如何入队呢?看图:
二叉树
假设要在这个二叉堆里入队一个单元,键值为2,那只需在数组末尾加入这个元素,而后尽量把这个元素往上挪,直到挪不动,通过了这种复杂度为Ο(logn)的操做,二叉堆仍是二叉堆。 方法
那如何出队呢?也不难,看图: im
出队必定是出数组的第一个元素,这么来第一个元素之前的位置就成了空位,把最后一个元素放到第一个位置再调整成正常状态就能够了。 数据
还有另外一种调整的方法
出队必定是出数组的第一个元素,这么来第一个元素之前的位置就成了空位,咱们须要把这个空位挪至叶子节点,而后把数组最后一个元素插入这个空位,把这个“空位”尽可能往上挪。