数据结构:堆的构建与排序思想(C语言)

1.什么是堆?

定义:

堆通常是可以看作一棵树的数组对象,堆是非线性数据结构,相当于一维数组。堆总是满足下列性质:

  • 堆中某个节点的值总是不大于或不小于其父节点的值;
  • 堆总是一棵完全二叉树。

将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。

在这里插入图片描述

下面我们将会学习:

  • 建初堆:如何将一个无序序列建成一个堆?
  • 调整堆:去掉堆顶元素,在堆顶元素改变之后,如何调整剩余元素成为一个新的堆?

因为建初堆要用到调整堆的操作,所以下面先讨论调整堆的实现。

2.调整堆

先看一个例子,如图a是一个堆,将堆顶元素97和堆中最后一个元素38交换后,如图b所示。由于此时除根节点外,其余节点均满足堆的性质,由此仅需自上至下进行一条路径上的结点调整即可。首先以堆顶元素38和其左、右子树根结点的值进行比较,由于左子树根节点的值76大于右子树根节点的值65,则将堆顶元素38与76交换;由于38替换了76之后,破坏了左子树的“堆”,则需进行和上述相同的调整直到叶子节点,那么此时左子树就满足了堆的性质,调整后的状态如图c所示。重复上述过程,将堆顶元素76和堆中最后一个元素27交换,此时右子树是被破坏的“堆”,则向上面一样进行调整,最后得到新堆。

在这里插入图片描述
上述过程就像过筛子一样,把较小的关键字逐层筛选下去,而较大的关键字逐层选上来。因此,称此为“筛选法”。

假设r[s+1] ~ r[m]已经是堆的情况下,按“筛选法”将r[s] ~ r[m]调整为以r[s]为根的堆,算法实现如下:

算法步骤:

从r[2s]和r[2s+1]中选出关键字较大者,假设r[2s]的关键字较大,比较r[s]和r[2s]的关键字。

  1. 若r[s].key>=r[2s].key,说明以r[s]为根的字数已经是堆,不必做任何调整。
  2. 若r[s].key<r[2s].key,交换r[s]和r[2s]。交换后,以r[2s+1]为根的子树仍为堆,如果以r[2s]为根的子树不是堆,则重复上述过程,将以r[2s]为根的子树调整为堆,直至进行到叶子结点为止。

伪代码:

      void HeapAdjust
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值