可以理解为由数组实现的完全二叉树,所有它没有使用父指针或者子指针。堆根据“堆属性”来排序,“堆属性”决定了树中节点的位置。 堆的常用方法: - 构建优先队列 - 支持堆排序 - 快速找出一个集合中的最小值(或者最大值) 堆分为两种:最大堆和最小堆,两者的差别在于节点的排序方式。 在最大堆中,_父节点的值比每一个子节点的值都要大_。在最小堆中,_父节点的值比每一个子节点的值都要小_。这就是所谓的“堆属性”,并且这个属性对堆中的每一个节点都成立 堆存在下标属性公式: 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]]