优先队列
二叉堆可分为大根堆和小根堆,在大根堆中,每个节点将大于或等于它的两个子节点,因此,根节点为大根堆的最大节点。可以使用数组表示二叉堆,x[0]
弃之不用,我们用x[1]
表示根节点。假定堆有 n 个元素并且满足大根堆的属性,那么需要满足 x[i]
<= x[i/2]
( n 取值 [2, n] )。
|
|
往堆中加入新节点:
新节点位于x[n]
,这时x[1, ..., n]
可能不满足堆的属性:
- 要是新节点大于它的父节点,则交换它们。
- 持续这个过程,直到新节点不大于它的父节点,即小于或等于它的父节点。
|
|
另一个操作时pop()
,也就是将最大的节点移除优先队列:
移出了最大的节点x[1]
,为了维持堆的属性,可以这样做:
- 将最后一个节点
elem
放到x[1]
,n
减一 。 - 为了维持堆的属性,要是
elem
小于它的两个子节点的较大者,交换他们。 - 持续这个过程,直到
elem
大于或等于它的两个子节点。
|
|
完整的代码展示:
堆排序
当我们了解了优先队列的实现原理,堆排序就容易实现了:
- 先是构造大根堆。
- 将数组分成两部分,
x[1, ..., i]
表示堆,x[i + 1, ..., n]
表示排定的数组。 - 交换
x[1]
和x[i]
,这时,x[2, ..., i - 1]
表示堆,x[i, ..., n]
表示排定的数组。 - 将
x[1]
下移到合适位置,这时,x[1, ..., i - 1]
表示堆,x[i, ..., n]
表示排定的数组。
|
|