如何根据一个数组建立最大堆

来源:互联网 发布:淘宝店铺模板源代码 编辑:程序博客网 时间:2024/06/03 20:49

From: http://zh.wikipedia.org/zh-cn/%E6%9C%80%E5%A4%A7%E5%A0%86


介绍
最大堆和最小堆是二叉堆的两种形式。

    最大堆:根结点的键值是所有堆结点键值中最大者的堆。
    最小堆:根结点的键值是所有堆结点键值中最小者的堆。

而最大-最小堆集结了最大堆和最小堆的优点,这也是其名字的由来。 最大-最小堆是最大层和最小层交替出现的二叉树,即最大层结点的儿子属于最小层,最小层结点的儿子属于最大层。 以最大(小)层结n点为根结点的子树保有最大(小)堆性质:根结点的键值为该子树结点键值中最大(小)项。
主要操作

不失一般性,只讨论根结点为最小层的情况。


插入
只需要将节点插在二叉树的最后一个叶子结点位置,然后比较它对它父亲节点的大小,如果大则停止;如果小则交换位置,然后对父亲节点递归该过程直至根节点。复杂度为O(log(n))。

一般来说,插入的位置可以不是最后一个叶子节点,可以作为任意中间节点的孩子节点插入,将这个叶子节点变为中间节点后,按上文所说的方法调整节点顺序以保证维持堆特性不变。


删除
要从堆中删除一个节点,用最后一个节点替换掉根节点,然后调整节点顺序以维持堆特性。



建堆既可以用堆调整方法将原数组调整为一个堆,也可以借助往堆中插入元素的方法从无到有的建立一个堆。

两种方法比较:

(1)借助堆调整建堆的时间复杂度为O(n)。借助插入法建堆的时间复杂度为O(nlgn) ,书上第二问要求证明这个复杂度,但是我认为插入法的复杂度也是O(n),因为它和堆调整的区别在于针对每个节点i,堆调整是自上向下进行调整,插入法是自下向上进行调整。

(2)对于同样的输入两个方法建立的堆可能不同。因为堆调整时,是i要跟它的两个子女进行比较,选出最大(小)的,但是插入x时,x只跟它的父节点进行比较。比如输入为2、3、4,堆调整建堆为4、3、2,插入法建堆为4、2、3。

插入法建最大堆代码如下:


原创粉丝点击