You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
|
可以理解为由数组实现的完全二叉树,所有它没有使用父指针或者子指针。堆根据“堆属性”来排序,“堆属性”决定了树中节点的位置。
|
|
|
|
|
堆的常用方法:
|
|
|
|
|
- 构建优先队列
|
|
|
|
|
- 支持堆排序
|
|
|
|
|
- 快速找出一个集合中的最小值(或者最大值)
|
|
|
|
|
|
|
|
|
|
堆分为两种:最大堆和最小堆,两者的差别在于节点的排序方式。
|
|
|
|
|
在最大堆中,_父节点的值比每一个子节点的值都要大_。在最小堆中,_父节点的值比每一个子节点的值都要小_。这就是所谓的“堆属性”,并且这个属性对堆中的每一个节点都成立
|
|
|
|
|
|
|
|
|
|
堆存在下标属性公式:
|
|
|
|
|
parent(i)=floor((i-1)/2) 向下取整
|
|
|
|
|
left(i)=2i+1
|
|
|
|
|
right(i)=2i+2
|
|
|
|
|
|
|
|
|
|
**插入操作**:以最大堆为栗子,插入其实就是把插入结点放在堆最后面,然后与父亲比较,如果父亲值小于它,那么它就和父亲结点交换位置,重复该过程,直到插入节点遇到一个值比它大的父亲或者它成为树根结点
|
|
|
|
|
以最大堆为栗子,在堆中插入值为20的结点(红色结点代表新进入)
|
|
|
|
|
![[20161207183935000.png]]
|
|
|
|
|
|
|
|
|
|
20明显大于它的父亲结点值,所以和7交换位置,交换后新的父亲值还是比它小,继续交换
|
|
|
|
|
![[微信截图_20221213114347.png]]
|
|
|
|
|
一步一步与它前面比它小的父亲结点交换位置,最后20成为根结点
|
|
|
|
|
最小堆同理,只不过要求父亲结点要比它小,如果父亲结点大于它,就得交换。
|
|
|
|
|
|
|
|
|
|
**删除操作**:
|
|
|
|
|
删除就是删除最大堆中的最大值或者最小堆中的最小值,也就是树根
|
|
|
|
|
以删除最大堆树根为例子,删除其实就是整个堆中少了一个结点,不妨把位于最后面的一个结点当成新的树根,然后与它左右孩子比较,与值最大并且值大于它的孩子进行交换(好好读这句话),直到它的孩子都是小于它的,或者变成树叶。
|
|
|
|
|
用最大堆为例,删除树根20:
|
|
|
|
|
![[20161207184700681.png]]![[20161207185133520.png]]
|
|
|
|
|
|
|
|
|
|
把最后的结点8提到树根,然后就按说明步骤,找到一个位置,它的孩子都小于它或者他变成树叶。
|
|
|
|
|
![[20161207185210411.png]]
|