堆《数据结构》

堆《数据结构》

  • 1. 堆排序
    • 1.1 建堆
      • 向上调整建堆
      • 向下调整建堆
    • 1.2 利用堆删除思想来进行排序
    • 1.3Top-k问题
  • 2.堆的时间复杂度

1. 堆排序

1.1 建堆

建大堆
建小堆

向上调整建堆

AdjustUp建堆

在这里插入图片描述

void AdjustUp(HPDataType* a, int child)
{// 初始条件// 中间过程// 结束条件int parent = (child - 1) / 2;//while (parent >= 0)while (child > 0){if (a[child] < a[parent]){Swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}
}void headsport(int* a, int n)//建堆
{for (int i = 0;i < n;i++){AdjustUp(a, i);//建堆(降序建大堆)向上调整建堆}
}
void test1()
{int arr[] = {1,5,3,2,7,9,4,6,8};headsport(arr, sizeof(arr) / sizeof(arr[0]));for (int i = 0;i < sizeof(arr) / sizeof(arr[0]);i++){printf("%d", arr[i]);}}

1:我们通过AdjustUp函数来建堆
2:在控制AdjustUp函数中a[child] < a[parent]的大小比较关系,这是控制建小堆,还是建大堆

如:a[child] < a[parent] 建小堆
在这里插入图片描述
a[child] > a[parent]建 大堆
在这里插入图片描述

向下调整建堆

AdjustDown

在这里插入图片描述
在这里插入图片描述

void AdjustDown(HPDataType* a, int n, int parent)
{// 先假设左孩子小int child = parent * 2 + 1;while (child < n)  // child >= n说明孩子不存在,调整到叶子了{// 找出小的那个孩子if (child + 1 < n && a[child + 1] < a[child]){++child;}if (a[child] < a[parent]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}
void headsport(int* arr, int n)
{//时间复杂度O(N)for (int i = (n-1-1)/2;i >=0;i--){AdjustDown(arr,n,i);//向下调整建堆}}
void test1()
{int arr[] = {1,5,3,2,7,9,4,6,8};headsport(arr, sizeof(arr) / sizeof(arr[0]));for (int i = 0;i < sizeof(arr) / sizeof(arr[0]);i++){printf("%d", arr[i]);}}

与AdjustUp同理:
arr[child]>arr[parent]->大堆
在这里插入图片描述
arr[child]<arr[parent]->小堆
在这里插入图片描述

1.2 利用堆删除思想来进行排序

1:建堆
升序:建大堆
降序:建小堆
2:建堆和堆删除中都用到了向下调整,因此掌握了向下调整,就可以完成堆排序。

实现图:
在这里插入图片描述

void headsport(int* arr, int n)
{for (int i = (n-1-1)/2;i >=0;i--){AdjustDown(arr,n,i);//向下调整建堆}int end = n - 1;//取最后一位数据while (end > 0)
{Swap(&arr[0], &arr[end]);//交换AdjustDown(arr, end, 0);//在向下建堆end--;
}
}
void test1()
{int arr[] = {1,5,3,2,7,9,4,6,8};headsport(arr, sizeof(arr) / sizeof(arr[0]));for (int i = 0;i < sizeof(arr) / sizeof(arr[0]);i++){printf("%d", arr[i]);}}
int main()
{test1();//CreateNdDate();/*TestHeap();*//*TestHeap3();*/return 0;
}

1.3Top-k问题

TOP-K问题:即求数据结合中前K个最大的元素或者最小的元素,一般情况下数据量都比较大。
比如:专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等

对于Top-K问题,能想到的最简单直接的方式就是排序,但是:如果数据
量非常大,排序就不太可取了(可能数据都不能一下子全部加载到内存中)。最佳的方式就是用堆来解决,基本思路如下:

1.用数据集合中前K个元素来建堆

·前k个最的元素,则建小堆
·前k个最的元素,则建大堆

2.用剩余的N-K个元素依次与堆顶元素来比较,不满足则替换堆顶元素

将剩余N-K个元素依次与堆顶元素比完之后,堆中剩余的K个元素就是所求的前K个最小或者最大的元素

#include<time.h>
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
void CreateNdDate()
{//造数据int n = 100000;srand(time(0));//随机种子const char* file = "daf.txt";FILE* fin = fopen(file, "w");//打开文件if (fin == NULL){perror("fopen error");return;}for (int i = 0;i < n;i++){int x = (rand() + i) % 1000000;//随机值fprintf(fin, "%d\n", x);//写入数据}fclose(fin);
}void TestHeap()
{int k;//获取前k个数printf("请输入k>");scanf("%d", &k);int* kminheap = (int*)malloc(sizeof(int) * k);if (kminheap == NULL){perror("mallco fail");return;}const char* file = "data.txt";FILE* fout = fopen(file, "r");if (fout == NULL){perror("fopen error ");return;}//读取文件前k个数for (int i = 0;i < k;i++){fscanf(fout,"%d", &kminheap[i]);}for (int i = (k - 1 - 1) / 2;i >= 0;i--)//建小堆{AdjustDown(kminheap, k, i);}//读取剩下n-k个数int x = 0;while (fscanf(fout,"%d", &x)>0);{if (x > kminheap[0]){kminheap[0] = x;AdjustDown(kminheap, k, 0);}}printf("最大前k个\n");for (int i = 0;i < k;i++){printf("%d\n", kminheap[i]);}}
int main()
{CreateNdDate();TestHeap();return 0;
}

在这里插入图片描述

2.堆的时间复杂度

因为堆是完全二叉树,而满二叉树也是完全二叉树,此处为了简化使用满二叉树来证明(时间复杂度本来看的就是近似值,多几个结点不影响最终结果):

向下调堆:从最后一个根节点开始调整
在这里插入图片描述
在这里插入图片描述

向上调堆:

调整次数:
第二层:向上调整 1次
第三层: 向上调整2次


第n层:向上调整n次

节点个数
第一层:2^0个
第二层:2^1个


第n层:2^n-1个

在这里插入图片描述

感谢大家观看!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/408227.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据分析:RFM客户价值度模型】

前言&#xff1a; &#x1f49e;&#x1f49e;大家好&#xff0c;我是书生♡&#xff0c;本阶段和大家一起分享和探索大数据技术RFM客户价值度模型&#xff0c;本篇文章主要讲述了&#xff1a;RFM客户价值度模型等等。欢迎大家一起探索讨论&#xff01;&#xff01;&#xff01…

机械学习—零基础学习日志(如何理解概率论7)

这里需要先理解伯努利试验。只有A与A逆&#xff0c;两种结果。 正态分布 再来一道习题~&#xff1a; 解析&#xff1a; 《概率论与数理统计期末不挂科|考研零基础入门4小时完整版&#xff08;王志超&#xff09;》学习笔记 王志超老师 &#xff08;UP主&#xff09;

5大分区管理器 - 最佳硬盘分区软件

分区是一个计算机术语&#xff0c;指的是在硬盘上创建多个区域&#xff0c;以便操作系统和分区管理软件能够高效地分别管理每个区域中的信息。经常使用电脑的人很可能会从拥有多个分区中受益。在硬盘上拥有分区的一个好处是&#xff0c;可以更轻松地将操作系统和程序文件与用户…

普元EOS-低开页面下拉选择控件加载列表数据

1 前言 普元EOS进行低代码开发页面可以高效提高开发效率&#xff0c;并且减少代码的出错机会。 在低代码开发页面的时候&#xff0c;表单页面中可以使用大量的常用控件。 本文将讲解下拉选择组件的使用。 2 下拉选择使用EOS内置字典作为数据源 下拉选择可从字典作为数据源&a…

粘包现象 | wireshark抓包的使用

在TCP协议的通信过程中&#xff0c;由于其面向流的特性&#xff0c;数据在传输过程中可能会发生粘包现象&#xff0c;即多个发送的数据包被接收方一次性接收&#xff0c;导致应用层无法正确解析数据。 1.粘包现象概述 TCP协议为了保证传输效率&#xff0c;可能会将多次send调…

ESP RainMaker OTA 自动签名功能的安全启动

【如果您之前有关注乐鑫的博客和新闻&#xff0c;那么应该对 ESP RainMaker 及其各项功能有所了解。如果不曾关注&#xff0c;建议先查看相关信息&#xff0c;知晓本文背景。】 在物联网系统的建构中&#xff0c;安全性是一项核心要素。乐鑫科技对系统安全给予了极高的重视。ES…

小程序学习day13-API Promise化、全局数据共享(状态管理)、分包

44、API Promise化 &#xff08;1&#xff09;基于回调函数的一部API的缺点&#xff1a;小程序官方提供的异步API都是基于回调函数实现的&#xff0c;容易造成回调地狱的问题&#xff0c;代码可读性、可维护性差 &#xff08;2&#xff09;API Promise化概念&#xff1a; 指…

【HarmonyOS NEXT星河版开发实战】页面跳转

个人主页→VON 收录专栏→鸿蒙综合案例开发​​​​​ 代码及其图片资源会发布于gitee上面&#xff08;已发布&#xff09; gitee地址https://gitee.com/wang-xin-jie234 目录 前言 界面功能介绍 界面构建过程 知识点概述 页面跳转 页面传参 全套源代码 Index页面 Sec…

C语言学习——文件

目录 十三、文件 13.1C文件概述 13.2文件类型指针 13.3文件的打开与关闭 文件的打开&#xff08;fopen函数&#xff09; 文件的关闭&#xff08;fclose函数&#xff09; 13.4文件的读写 fputc函数和fgetc函数&#xff08;putc函数和getc函数&#xff09; fread函数和fw…

【qt】自定义信号

我们在上篇中&#xff0c;服务器收到的消息是由线程类去处理的&#xff0c;消息在线程类中&#xff0c;传不到widget中的ui中去&#xff0c;如果我们要在界面显示客户端的消息&#xff0c;必须通过自定义信号. 1.构建信号 当线程收到信息&#xff0c;就会被填充在ba中&#xf…

PHPShort轻量级网址缩短程序源码开心版,内含汉化包

需要网址缩短并且想获得更多有关链接点击率和流量的数据分析&#xff0c;那么 PHPShort 可能是一个非常好的选择。PHPShort 是一款高级的 URL 缩短器平台&#xff0c;可以帮助你轻松地缩短链接&#xff0c;并根据受众群体的位置或平台来定位受众。 该程序基于 Laravel 框架编写…

Fiddle抓手机app的包

前言 本次文章讲述的是&#xff0c;fiddle获取手机代理&#xff0c;从而获取手机app的http、https请求&#xff01; 一.下载安装汉化Fiddle 1.点击Fiddler官网下载链接&#xff1a;Download Fiddler Web Debugging Tool for Free by Telerik 2.直接运行&#xff0c;选择自己需…

Linux:进程的概念,进程相关函数

一、进程的概念 1.进程 进程是系统进行资源分配和调度的一个独立单元&#xff0c;它是操作系统结构的基础。进程是程序的一次执行过程&#xff0c;包含了程序代码、当前活动、系统资源&#xff08;如CPU、内存、文件等&#xff09;的使用情况等信息。每个进程都有自己独立的内…

AUTOSAR_EXP_ARAComAPI.pdf的第4章笔记

4 Fundamentals 为了理解AUTOSAR_EXP_ARAComAPI.pdf的第4章内容&#xff0c;生搬硬套的翻译了一把&#xff0c;准备先囫囵吞枣&#xff0c;再仔细理解。因为这些内容的理解也不是一时半会儿的。所以先放上来。 AUTOSAR_EXP_ARAComAPI.pdf的概述 因此&#xff0c;ara::com不提…

VS2022 - 制作自己的C#类库dll,并输出Unity识别的pdb调试信息文件

然后编写库代码&#xff0c;设置dll生成目录 *** 输出unity可以识别的pdb调试信息文件 *** 右键项目-属性-生成-高级-调试信息&#xff1a;可移植(Portable PDB) 这是因为Unity只能识别MDB和Portable PDB文件 这样设置后&#xff0c;把dll和pdb文件放入到Unity中同文件夹下&…

002、架构_概览

GoldenDB 主要由管理节点、计算节点、数据节点、全局事务节点等模块组成&#xff0c;各个节点无需共享任何资源&#xff0c;均为独立自治的通用计算机节点&#xff0c;之间通过高速互联的 网络通讯&#xff0c;从而完成对应用数据请求的快速处理和响应。 管理节点在数据库中主要…

【JVM】剖析字符串与数组的底层实现(一)

剖析字符串与数组的底层实现 字符数组的存储方式 JVM有三种模型: 1.Oop模型:Java对象对应的C对象2.Klass模型:Java类在JVM对应的C对象3.handle模型 字符串常量池 即String Pool&#xff0c;但是JVM中对应的类是StringTable&#xff0c;底层实现是一个hashtable,如代码所示 …

三级_网络技术_42_综合题(命令)

一、 如图所示&#xff0c;某园区网用10Gbps的POS技术与intemet相连&#xff0c;POS接囗的帧格式是SDH。在R3上配置一个oopback接口&#xff0c;"P地址为10.2.15.1&#xff0c;路由协议的选择方案是&#xff0c;园区网内部采用OSPF动态路由协议&#xff0c;园区网与Inter…

如何使用ssm实现基于面向对象的学生事务处理系统分析与设计

TOC ssm138基于面向对象的学生事务处理系统分析与设计jsp 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进行科学化…

go中 panicrecoverdefer机制

go的defer机制-CSDN博客 常见panic场景 数组或切片越界&#xff0c;例如 s : make([]int, 3); fmt.Println(s[5]) 会引发 panic: runtime error: index out of range空指针调用&#xff0c;例如 var p *Person; fmt.Println(p.Name) 会引发 panic: runtime error: invalid m…