当前位置: 首页 > news >正文

数据结构-堆的实现和应用

目录

1.堆的概念

2.堆的构建

3.堆的实现

4.堆的功能实现

4.1堆的初始化

4.2堆的销毁

4.3堆的插入

4.3.1向上调整

4.4堆的删除

4.4.1向下调整法

​编辑4.5取堆顶

5. 向上调整法和向下调整法比较

 6.堆的应用

6.1TOP-K问题

6.2TOP-K思路

6.2.1用前n个数据来建堆

6.2.2剩下的N-K 

6.3示例


1.堆的概念

堆的底层是数组,所以堆也是一种特殊的数组。

堆分为大堆和小堆

  • 大堆:父节点不小于子节点
  • 小堆:父节点不大于子节点

2.堆的构建

已经提到堆是一种数组,那么要怎么实现呢。

先以小堆为例,已知父节点不小于子节点,使用数组,数组下标0是根节点,1和2是他的子节点,接着1的子节点是3和4,2的子节点是5和6,这样就可以实现一个堆了。

3.堆的实现

既然是数组,就要有指针,容量大小。

4.堆的功能实现

4.1堆的初始化

4.2堆的销毁

4.3堆的插入

一直到这一步,都是和栈是相同的,因为我们插入数据了,这时我们无法保证这是一个堆,所以此时要进行向上调整。

4.3.1向上调整

因为此时插入是数据再最下面,所以要和上面的进行比较调整。

4.4堆的删除

我们是删除堆的最后一个元素,要怎么删除呢,我们可以将最后一个元素和第一个元素进行交换,然后使堆向下调整即可。

        

4.4.1向下调整法

4.5取堆顶

5. 向上调整法和向下调整法比较

推导时间复杂度,由于用图来表示有些难度,这里直接用笔写出来

这是向下调整法的推导过程

向下调整建堆的时间复杂度如图

下面是向上调整建堆的时间复杂度推导

总结:向上调整算法建堆是优于向下调整建堆的。

 6.堆的应用

6.1TOP-K问题

这种问题通常是在较大的数据样本中取出其中的最值,这时就可以通过堆来完成。

通常这类问题样本较大,排序就不太可取,可以建堆来实现。

6.2TOP-K思路

6.2.1用前n个数据来建堆

求最大的前n个就建小堆

求最小的前n个就建大堆

6.2.2剩下的N-K 

用剩下的N-K个数据来和堆顶数据比较,不满足就替换堆顶元素

6.3示例

#define _CRT_SECURE_NO_WARNINGS 1
#include"Heap.h"
#include<time.h>
void test()
{HP hp;HPInit(&hp);HPPush(&hp, 2);HPPush(&hp, 4);HPPush(&hp, 1);HPPush(&hp, 1); printf("%d", HPTop(&hp));}
void CreateNDate()
{int n = 10000;srand(time(0));const char* file = "data.txt";FILE* fin = fopen(file, "w");if (file == NULL){perror("fopen fail");return;}for (int i = 0; i < n; i++){int x = (rand() + i) % 1000000;fprintf(fin, "%d\n", x);}fclose(fin);
}
void topk()
{int k = 0;printf("输入k的值\n");scanf("%d", &k);const char* file = "data.txt";FILE* fout = fopen(file, "r");int* arr = (int*)malloc(sizeof(int) * k);for (int i = 0; i < k; i++){fscanf(fout, "%d", &arr[i]);}//建堆for (int i = (k - 1 - 1) / 2; i >= 0; i--){AdjustDown(arr, i, k);}int x = 0;while (fscanf(fout, "%d", &x) != EOF){if (x > arr[0]){arr[0] = x;AdjustDown(arr, 0, k);}}for (int i = 0; i < k; i++) {printf("%d ", arr[i]);}fclose(fout);
}int main()
{CreateNDate();topk();return 0;
}

http://www.lryc.cn/news/492558.html

相关文章:

  • 数据分析的尽头是web APP?
  • YOLO系列论文综述(从YOLOv1到YOLOv11)【第3篇:YOLOv1——YOLO的开山之作】
  • 容器和它的隔离机制
  • 【数据结构与算法】排序算法总结:冒泡 / 快排 / 直接插入 / 希尔 / 简单选择 / 堆排序 / 归并排序
  • Windows Serv 2019 虚拟机 安装Oracle19c,图文详情(超详细)
  • 数字孪生开发之 Three.js 插件资源库(2)
  • 小米C++ 面试题及参考答案下(120道面试题覆盖各种类型八股文)
  • OpenOCD之J-Link下载
  • 华为云云连接+squid进行正向代理上网冲浪
  • 情绪识别项目
  • 【RISC-V CPU debug 专栏 2.2 -- Hart DM States】
  • 从零样本到少样本学习:一文读懂 Zero-shot、One-shot 和 Few-shot 的核心原理与应用!
  • 【LC】3101. 交替子数组计数
  • 如何构建SAAS项目
  • 树莓派搭建NextCloud:给数据一个安全的家
  • 深入解读 MongoDB 查询耗时:Execution 和 Fetching 阶段详解
  • frida_hook_dlopen(当年到lib目录下找发现一个so都没有,hook下dlopen)
  • Zero to JupyterHub with Kubernetes中篇 - Kubernetes 常规使用记录
  • WordCloud去掉停用词(fit_words+generate)的2种用法
  • Python 中如何处理异常?
  • C++——多态(下)
  • qsort函数详解+代码展示
  • leetcode hot100【LeetCode 136. 只出现一次的数字】java实现
  • (免费送源码)计算机毕业设计原创定制:Java+ssm+JSP+Ajax SSM棕榈校园论坛的开发
  • 对抗攻击算法:FGSM和PGD
  • 【八股文】小米
  • xtu oj 众数
  • ENVI计算ROI分离度为灰色compute roi separability
  • Adaboost集成学习 | Python实现基于NuSVR-Adaboost多输入单输出回归预测
  • Python学习第十三天--面向对象,类和对象