二叉堆
二叉堆描述
是一棵完全二叉树,对于树的每一个节点值x,该节点的所有祖先节点值都>=x或<=x。其中>=x的称为大顶堆,<=x的称为小顶堆。该数据结构常用于实现优先队列。
图片示例如下:
数据结构
为了方便,采用数组形式存储堆数据。数组每一个位置表示一个节点,通过某个节点的索引位置可以快速计算出其父节点和子节点的索引位置。为了方便计算,将索引1作为堆的堆顶节点。
索引下标计算:对于某一节点的索引i,父节点下标为i/2,左子节点下标为i*2,右子节点下标为i*2+1。
节点的操作-上浮
以小顶堆为例,某节点上浮的过程:比较该节点与父节点值大小关系,如果小于父节点值(表示可以上浮),则交换该节点和父节点的值。然后对父节点上浮,直到不能上浮或到了堆顶节点。
节点的操作-下沉
以小顶堆为例,某节点下沉的过程:比较该节点与两个子节点的大小关系,如果有子节点的值小于该节点的值(表示可以下沉),则交换该节点与值最小的子节点的值。然后对交换了值的子节点进行下沉操作,直到不能下沉或者无子节点。
插入数据
在堆的尾部插入一个新的节点(对数组来说就是在数组末尾增加一个元素),然后对该节点进行上浮操作。待稳定后得到的就是新的最小/最大堆。树的深度为lgn,所以该操作的时间复杂度为O(lgn)。
弹出堆顶
将堆顶节点与堆尾部节点交换(对数组来说就是将数组首元素与尾元素交换),然后返回堆尾节点元素,对堆顶节点进行下沉操作。该操作的时间复杂度为O(lgn)。
堆的构造
现有初始数组,即为初始的堆。
构造方法1:从第二层开始,对每个节点执行上浮操作。总体时间复杂度为O(nlgn)。
构造放法2:从倒数第二层开始,对每个节点执行下沉操作。总体时间复杂度为O(n)。
堆排序
构造好堆后,弹出堆顶元素,直到堆中无元素。时间复杂度为O(nlgn)。