二叉堆

来源:互联网 发布:读读日报 关注知乎日报 编辑:程序博客网 时间:2024/06/14 10:00

堆是一颗具有特定性质的二叉树。堆的基本要求是堆中所有结点的值必须大于或者等于(或者小于等于)其孩子结点的值。这也是堆的性质,堆还有一个性质,就是当h>0时,所有叶子结点都处于第h层或者h-1层。(h为树的高度),堆应该是一颗完全二叉树。

堆分为两类:
最大堆: 结点的值必须大于或者等于其孩子结点的值。

这里写图片描述

最小堆:结点的值必须小于或者等于其孩子结点的值。

堆的表示:
堆在形式上是一颗完全二叉树,用数组来存储他不会浪费任何空间。

这里写图片描述

第i个位置上的结点,其双亲结点的处于在(i-1)/2 位置上。
第i位置上的节点,其左孩子结点的位置为2*i+1 右孩子结点的位置为2*i+2

堆化
当插入一个元素到堆中的时候,这个元素可能不满足堆的性质。在这种情况下,需要调整堆中元素的位置使之重新变为堆。这个过程叫做堆化。
在最大堆中,要堆化一个元素,需要找到它的孩子结点中的最大值,然后将它与当前元素进行交换,重复该过程,直到每个结点都满足堆的性质。这个过程又称之为向下渗透。

在堆中的尾部插入一个元素时,需要从下往上来比较和调整元素。即需要将它与它的双亲进行大小比较和交换。直到所有元素满足堆的性质。这个过程又称之为向上渗透。时间复杂度为O(logn)

堆的排序:

堆排序的算法首先将所有元素插入堆中,然后从堆的跟结点依次删除他们,直到堆空。堆排序可以利用现有数组就地完成排序。具体的做法是,当删除一个元素时,只数组中第一个元素与最后一个元素交换位置而不是真正地从数组中移除该元素,同时减少堆的大小,然后再对一个元素进行堆化。持续这个过程,直到堆的大小为1.。
插入算法和删除算法(一个元素)的时间复杂度都是 O(logn) 堆排序的时间复杂度为O(nlogn) (有n个元素)