堆的实现及应用

下面用C语言介绍堆的实现以及应用

1. 堆的简介

堆是一颗完全二叉树。这里所说的堆是一种非连续的数据结构,与操作系统内存分布的堆是两回事,它们没有任何联系。
堆有以下特点:

  1. 堆中某个结点的值总是不大于或不小于其父结点的值
  2. 堆是一颗完全二叉树
  3. 堆的逻辑结构是一颗完全二叉树,但是物理结构是顺序表

小堆: 任何一个结点的值都大于或者等于孩子结点的值
小堆: 任何一个结点的值都小于或者等于孩子结点的值

数据下标计算父子关系公式在这里插入图片描述

2. 堆的实现

这些介绍堆的以下接口在这里插入图片描述

HeapInit

在这里插入图片描述

HeapDestroy

在这里插入图片描述

HeapPush

在这里插入图片描述
这里使用了向上调整算法
在这里插入图片描述

HeapPop

在这里插入图片描述
这里使用了向下调整算法
在这里插入图片描述

3. 堆的应用

堆排序

升序建大堆,降序建小堆

在这里插入图片描述

TopK问题

TopK问题即在N个数中(N非常大)选出前K个最大或者最小的数
这里以选出前K个最大的数为例
选出最大的前K个数可以建大堆也可以建小堆

如果建大堆,思路就和堆排序的思路一样,都是需要先建堆,然后进行选数即可,不同的是这样选数只需要选K次。时间复杂度为N + logK。但是这个方法有一定的弊端。我们不妨设想,当数据非常大的时候,也就是不能全部放在内存的时候,比如10亿个整数,需要40个G的空间来存储,这个时候这40个G就只能放在磁盘中了。我们建堆的话就只能分批次在磁盘中拿数据,然后分部分地建堆,最后再将每部分最大的数据放在一起。这样的话,效率就减慢了,但是也不能说太慢,也在我们可以接受的范围之内。
如果建小堆,用小堆来选出最大的K个数,小堆的第一个数是最小的那个数,然后再便利剩下N - K个 数,当有数比小堆中最小的那个数更大时,就将最小的那个数的值赋给堆顶的数,然后使用向下调整算法。时间复杂度为
logK + (N - K)* logK。数据较少时和建大堆的时间复杂度相差不大,但是当数据较大它的优势就很明显了。

结论是选最大K个数建小堆更好,选最小K个数建大堆更好

下面给出选最大K个数建小堆的代码
在这里插入图片描述

这里再尝试使用堆来选出磁盘数据中最大的K个数

首先创建文件,并在文件中写入大量的随机数。在这里插入图片描述
再随便放入几个比更大的数在文件中,这样做的目的是验证我们最终选出的数是否是最大的数。

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zzu_ljk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值