定义
(1)堆是一个完全二叉树。(除了叶子节点,其他节点的值都是满的)
(2)堆中每一个节点的值都必须大于等于(或者小于等于)其左右节点的值。 对于每个节点的值大于等于子树的值,称为大顶堆。反之称之为小顶堆。
图示(大顶堆):
堆的实现
因为堆的执行(完全二叉树),他适合用数组直接进行存储。数组中下标为i的节点的左右节点为为i*2, i*2+1。而任意一个节点i的父节点是i/2。这里我们在平时可以选择下边1作为第一个节点,有助于理解和代码的书写。如果我们用下标0作为第一个节点的话, 其子节点为(i+1)/2 ,(i+1)/2 +1。
堆的操作
插入操作 :在向堆中插入一个数据时,我们还是需要继续满足堆的特性。我们先将数据插入到数组的尾部,然后进行调整,让其重新满足堆的特性,这个过程就叫作堆化。
堆化过程:从下往上堆化。
从下往上堆化过程:先将数据插入到数组尾部,然后比较其父节点关系,然后继续进行交换。直到最后满足堆的性质。
实现代码
明天补上
删除操作:在堆中我们一般都是删除堆顶的元素,很少删除指定下标节点的情况。所以我们还是只讨论对于堆顶元素的删除情况。
堆化过程:从上往下堆化。
从上到下进行堆化过程:在堆化的图示过程中我们可以看待,这种情况会导致最后完成之后不能满足完全二叉树的情况。从而也就破坏了堆的性质。
鉴于此情况,我们可以将待删除的元素和数组中最后一个元素进行对调,然后从堆顶从一次向下进行堆化,直到最后满足定义。这样完毕之后他还是满足完全二叉树的定义。图示如下:
代码实现
复杂度分析:在对对进行操作时都不需要申请辅助空间,所以其空间复杂度为O(1),而对于时间复杂度,由于是以完全二叉树的性质进行存储的,从根节点到叶子节点的高度为log n ,因此在堆化的过程中时间,无论是插入操作还是删除操作其时间复杂度为O(log n)。
原文:https://www.cnblogs.com/GoodRnne/p/10692970.html