数据结构温习3(堆结构)

什么是堆

堆是一种满足以下条件的树:

堆中的每一个节点值都大于等于(或小于等于)子树中所有节点的值。或者说,任意一个节点的值都大于等于(或小于等于)所有子节点的值。

例如:

 

第1个和第2个是堆。第1个是最大堆,每个节点都比子树中所有节点大。第2个是最小堆,每个节点都比子树中所有节点小。

第3个不是,第三个中,根结点1比2和15小,而15却比3大,19比5大,不满足堆的性质。

堆的用途

相对于有序数组而言,堆的主要优势在于更新数据效率较高

堆的存储

之前介绍树的时候说过,由于完全二叉树的优秀性质,利用数组存储二叉树即节省空间,又方便索引(若根结点的序号为1,那么对于树中任意节点i,其左子节点序号为 2*i,右子节点序号为 2*i+1)。

为了方便存储和索引,(二叉)堆可以用完全二叉树的形式进行存储。存储的方式如下图所示:

 

堆的操作

堆的更新操作主要包括两种 : 插入元素 和 删除堆顶元素。操作过程需要着重掌握和理解

(用通俗的话语来讲:堆是一个公平的公司,有能力的人自然会走到与他能力所匹配的位置)

插入元素

插入元素,作为一个新入职的员工,初来乍到,这个员工需要从基层做起

1.将要插入的元素放到最后

 (有能力的人会逐渐升职加薪,是金子总会发光的!!!)

2.从底向上,如果父结点比该元素大,则该节点和父结点交换,直到无法交换

 

删除堆顶元素

根据堆的性质可知,最大堆的堆顶元素为所有元素中最大的,最小堆的堆顶元素是所有元素中最小的。当我们需要多次查找最大元素或者最小元素的时候,可以利用堆来实现。

删除堆顶元素后,为了保持堆的性质,需要对堆的结构进行调整,我们将这个过程称之为"堆化",堆化的方法分为两种:

  • 一种是自底向上的堆化,上述的插入元素所使用的就是自底向上的堆化,元素从最底部向上移动。
  • 另一种是自顶向下堆化,元素由最顶部向下移动。

自底向上堆化

在堆这个公司中,会出现老大离职的现象,老大离职之后,他的位置就空出来了

首先删除堆顶元素,使得数组中下标为1的位置空出。

 

那么他的位置由谁来接替呢,当然是他的直接下属了,谁能力强就让谁上呗

比较根结点的左子节点和右子节点,也就是下标为2,3的数组元素,将较大的元素填充到根结点(下标为1)的位置。

 

这个时候又空出一个位置了,老规矩,谁有能力谁上

一直循环比较空出位置的左右子节点,并将较大者移至空位,直到堆的最底部

 这个时候已经完成了自底向上的堆化,没有元素可以填补空缺了,但是,我们可以看到数组中出现了“气泡”,这会导致存储空间的浪费。接下来我们试试自顶向下堆化。

自顶向下堆化

自顶向下的堆化用一个词形容就是“石沉大海”,那么第一件事情,就是把石头抬起来,从海面扔下去。这个石头就是堆的最后一个元素,我们将最后一个元素移动到堆顶。

 

 

 然后开始将这个石头沉入海底,不停与左右子节点的值进行比较,和较大的子节点交换位置,直到无法交换位置。

 

堆的操作总结

  • 插入元素 :先将元素放至数组末尾,再自底向上堆化,将末尾元素上浮
  • 删除堆顶元素 :删除堆顶元素,将末尾元素放至堆顶,再自顶向下堆化,将堆顶元素下沉。也可以自底向上堆化,只是会产生“气泡”,浪费存储空间。最好采用自顶向下堆化的方式

 

堆排序

堆排序的过程分为两步:

  • 第一步是建堆,将一个无序的数组建立为一个堆
  • 第二步是排序,将堆顶元素取出,然后对剩下的元素进行堆化,反复迭代,直到所有元素被取出为止。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值