堆-原理到应用——用最简单的代码让你读懂堆
作者:互联网
堆-原理到应用
文章目录
堆的介绍
- 完全二叉树:完全二叉树是满二叉树去除最后N个节点之后得到的树( N ≥ 0 , N ∈ N ∗ N \geq0, N \in N^* N≥0,N∈N∗)
- 大根堆:节点的父亲节点比自身节点大,比如根节点的值为 8 8 8,比其子节点 7 7 7, 6 6 6大,其余的类似。
- 小根堆:节点的父亲节点比自身节点小,比如根节点的值为 1 1 1,比其子节点 2 2 2, 3 3 3的值要笑,其余的也类似。
堆的实现
如何存储一个堆
堆的存储是使用数组实现的,下标从0开始从左至右从上到下,依次递增,例如上述的小根堆存储在数组中就是
[1, 2, 3, 4, 5, 6, 7]
对应的下标为 0 , 1 , 2 , 3 , 4 , 5 , 6 0, 1, 2, 3, 4, 5, 6 0,1,2,3,4,5,6
如何将一个数组变成一个堆
从最后一个有孩子节点 (节点下标为 M M M)的元素开始,先将以改元素为根节点的子树变成一个堆,然后下标减 1 1 1,再将下标为 M − 1 M - 1 M−1的节点所对应的子树变成堆,依次递减进行,知道根节点。示例如下(以小根堆为例):
-
找到第一个有孩子节点的,由上图容易知道,第一个有孩子节点的值为 5 5 5,其下标为 3 3 3,它对应的子树为:
如果需要将上面的子树变成一颗小根堆,只需要将 5 5 5和 1 1 1对应节点互换位置即可(不能和 2 2 2换,如果和 2 2 2换 2 > 1 2>1 2>1不符合小根堆的性质),换完之后的结果为:
-
然后将下标减 1 1 1,即为 2 2 2,对应的元素为 6 6 6,现在也需要将其对应的子树变成一颗小根堆,即需要将 6 6 6和 2 2 2互换,互换之后的结果为:
-
继续将下标减 1 1 1,然后进行相同的操作,很容易知道将 7 7 7和 1 1 1互换位置,互换之后的结果为:
从上面的图可以知道,当 1 1 1和 7 7 7互换之后,子树 [ 7 , 2 , 5 ] [7, 2, 5] [7,2,5]不是一颗小根堆了,那怎么办?再将子树 [ 7 , 2 , 5 ] [7, 2, 5] [7,2,5]变成小根堆即可,所以再进行一次小根堆操作即可,将 7 7 7, 2 2 2进行互换即可,交换之后的结果为:
在上述的树中,交换过程已经完成了,但是如果节点的数目非常大,或者说下面的子树可能又出现了不符合小根堆的情况怎么办?那就一直循环走下去,直到没有孩子节点或者已经满足小根堆的性质。
-
最后再对节点 8 8 8进行相关操作,得到的结果如下:
-
再对子树进行堆化 ( h e a p i f y ) (heapify) (heapify)操作:
-
在进行堆化,得到最终结果
以上就是将一个完全二叉树变成一颗小根堆的过程,大根堆的过程非常类似,即将较大的数作为父亲节点即可,就不在进行陈述~~~
标签:子树,下标,代码,读懂,二叉树,互换,原理,小根堆,节点 来源: https://blog.csdn.net/qq_45537774/article/details/114858420