二叉树-堆应用(1)

目录

堆排序

整体思路

代码实现

Q1建大堆/小堆

Q2数据个数和下标

TopK问题

整体思路

代码实现

Q1造数据CreateData

Q2建大堆/小堆


  • 建堆的两种方法
  • 这里会用到前面的向上/向下调整/交换函数。向上调整&向下调整算法-CSDN博客

堆排序

整体思路

  • 建堆(直接把数组搞成堆)升序:建大堆  降序:建小堆
  • 利用堆删除的思想来进行堆排序 (就是模拟堆删除的过程,但是实际并不删除堆)
  • 1:交换头尾
  • 2:向下调整(除去最后一个元素&&最后一个元素已经排好序了)
  • 3:循环重复上述过程
  • 建队有两种方法:插入(向上调整建堆)/向下调整建堆(下篇细讲)
  • 建堆和堆删除中都用到了向下调整,因此掌握了向下调整,就可以完成堆排序。

代码实现

//堆排序:本质直接在数组里面排序
void test1(int* a, int size)
{//方法1的时间/空间复杂度都很低//方法2//1.向上调整建堆 建堆--建的小堆--降序 建大堆--升序for (int i = 0; i < size; i++){AdjustUp(a, i);}//1.向下调整建堆for (int i = (size - 1 - 1) / 2; i >= 0; i--)//i=0的时候到达根节点此时就是全部向下调整{Adjustdown(a, size, i);//这里的size不确定,但是肯定比size小所以取最大就size}//2.while (size){//交换Swap(&a[0], &a[size - 1]);//向下调整(除去已经排序好的元素)Adjustdown(a, size-1, 0);//到达下一个交换的位置size--;}
}
int main()
{int a[10] = { 2,3,7,5,4,3,9,7,6,10 };int size = sizeof(a) / sizeof(a[0]);//10个数==最后一个数的下一个数的下标test1(a, size);//3.打印for (int i = 0; i < size; i++){printf("%d ", a[i]);}return 0;
}

Q1建大堆/小堆

升序:建大堆 

降序:建小堆

 

Q2数据个数和下标

size:指向最后一个元素的下一个位置

交换首位元素:最后一个元素的下标size-1

出去排好的元素向下调整个数:为size-1(-1除去排好的元素) 

 

TopK问题

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

整体思路

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

  • 用数据集合中前K个元素来建堆
  • 前k个最大的元素,则建小堆;前k个最小的元素,则建大堆
  • 用剩余的N-K个元素依次与堆顶元素来比较,不满足则替换堆顶元素
  • 将剩余N-K个元素依次与堆顶元素比完之后,堆中剩余的K个元素就是所求的前K个最小或者最大的元素。

代码实现

void CreateDate()//创造数据
{int n = 1000000;srand((unsigned int)time(NULL));//随机数的种子//打开文件const char* file = "data.txt";//文件指针FILE* fin = fopen(file, "w");//以写的形式打开文件状态指针if (fin == NULL)//打开失败{perror("fopen error");return;}//写文件for (int i = 0; i < n; i++){int r = (rand() + i) % 1000000;fprintf(fin, "%d\n", r);}//关闭文件fclose(fin);
}void test2(int K)
{//打开文件const char* file = "data.txt";//文件指针FILE* fout = fopen(file, "r");//以写的形式打开文件状态指针if (fout == NULL)//打开失败{perror("fopen error");return;}//读取文件//开辟数组空间存放小堆int* a = (int*)malloc(sizeof(int) * K);if (a == NULL){perror("malloc error");return;}for (int i = 0; i < K; i++){fscanf(fout, "%d", &a[i]);//读取放入数组AdjustUp(a, i);//建小堆}//一直读取并且比较int n = 0;while (fscanf(fout,"%d", &n) != EOF){if (a[0] < n){a[0] = n;Adjustdown(a, K, 0);}}//打印int i = 0;for (i = 0; i < K; i++){printf("%d ", a[i]);}//释放空间/关闭文件free(a);fclose(fout);
}int main()
{//CreateDate();//创造数据int K = 8;test2(K);//TopK问题--小堆--取前K个最大的数return 0;
}

Q1造数据CreateData

  • 打开文件
  • 写文件
  • 关闭文件
  • 随机数&随机数的种子&产生随机数
  • 随机数最多3万个
  • 文件指针&文件状态指针
  • 想要产生的随机数在100万以内:%100万
  • 测试:去文件里面修改值大于>100万的数,查看是否打印出来的是修改后的数据。
void CreateDate()//创造数据
{int n = 1000000;srand((unsigned int)time(NULL));//随机数的种子//打开文件const char* file = "data.txt";//文件指针FILE* fin = fopen(file, "w");//以写的形式打开文件状态指针if (fin == NULL)//打开失败{perror("fopen error");return;}//写文件for (int i = 0; i < n; i++){int r = (rand() + i) % 1000000;fprintf(fin, "%d\n", r);}//关闭文件fclose(fin);
}

Q2建大堆/小堆

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

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

 

🙂感谢大家的阅读,若有错误和不足,欢迎指正

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

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

相关文章

【经典项目】Java小游戏 —— 会说话的汤姆猫

一、游戏回顾 【预期效果】 【玩法介绍】 1、 和它说话&#xff0c;它将用有趣的声音重复你的话。 2、打它的头&#xff0c;它会装成被打的样子&#xff0c;连续打还会晕倒&#xff1b;抚摸肚子&#xff0c;它会打呼噜&#xff1b;打肚子&#xff0c;它会装肚子疼&#xff1b…

AVR 328pb定时器0基本介绍和使用

AVR 328pb定时器0基本介绍和使用 &#x1f4cc;参考ATmega328PB文档.&#x1f4cd;结合参考同架构lgt8f328p中文文档&#xff1a;http://www.prodesign.com.cn/wp-content/uploads/2023/03/LGT8FX8P_databook_v1.0.4.pdf &#x1f4d7;定时器0基本功能描述 两个独立的输出比较…

记一次java项目本地正常执行,打完包之后执行发现没有对应的类或配置的问题

1、起因 线上有个spark的任务出了问题&#xff08;该任务是通过sparkstreaming读取kafka中的数据&#xff0c;处理完之后推到es中&#xff09;&#xff0c;问题出在kafka中数据是有更新的&#xff0c;但是es中的对应索引中的数据却只更新到月初&#xff0c;因此我需要排查处理…

JavaSE-项目小结-IP归属地查询(本地IP地址库)

一、项目介绍 1. 背景 IP地址是网络通信中的重要标识&#xff0c;通过分析IP地址的归属地信息&#xff0c;可以帮助我们了解访问来源、用户行为和网络安全等关键信息。例如应用于网站访问日志分析&#xff1a;通过分析访问日志中的IP地址&#xff0c;了解网站访问者的地理位置分…

Linux进程通信基础

前要&#xff1a;本节内容主要是管道和共享内存块&#xff0c;而且我们需要明白我们所讲的进程通信本质是为了在内存中传递数据&#xff08;看到同一份资源&#xff09;。 而实际上&#xff0c;我们也可以通过磁盘传递数据&#xff0c;但是为什么不这么做呢&#xff1f;很简单&…

【Linux】Daemon守护进程详解

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;Linux系列专栏&#xff1a;Linux基础 &#x1f525; 给大家…

DRV8313和L298N都是电机驱动,一个是驱动三相FOC无刷直流电机的,一个是驱动有刷电机,使stm32控制无刷电机简单入门知识

DRV8313和L298N都是电机驱动器&#xff0c;但它们之间存在一些关键的区别&#xff1a; DRV83131&#xff1a; 由德州仪器&#xff08;TI&#xff09;制造。 具有集成的场效应晶体管&#xff08;FET&#xff09;。 最大电压为65V。 峰值电流为3A。 适用于三相电机驱动。 L298N…

性能测试常用术语

之前在性能测试过程中&#xff0c;对于某些其中的术语一知半解&#xff0c;导致踩了很多坑。这篇博客&#xff0c;就常见的一些性能测试术语进行一次浅析。。。 负载 对被测系统不断施加压力&#xff0c;直到性能指标超过预期或某项资源使用达到饱和&#xff0c;以验证系统的处…

基于FPGA的OFDM基带发射机的设计与实现

文章目录 前言一、OFDM描述二、本系统的实现参照 1.IEEE 802.11a协议主要参数2.不同调制方式与速率 3. IFFT映射关系4. IEEE 802.11a物理层规范5. PPDU帧格式三、设计与实现 1.扰码2.卷积编码与删余3.数据交织4.符号调制5.导频插入6.IFFT变换 7.循环前缀&加窗8.训练序列生成…

kubekey网页版安装k8s集群操作流程

kubekey可以一键拉起k8s集群并完成kubesphere的部署&#xff0c;以后kubekey简称kk。kk 3.2版本以前都是在宿主机上完成对应的创建集群、添加节点、升级等操作的&#xff0c;3.2版本后开始往页面操作的方向演进&#xff0c;kk 3.2版本现在还是alpha&#xff0c;所以不推荐在生产…

java面向对象基础(面试)

一、面向对象基础 1. 面向对象和面向过程的区别 面向过程把解决问题的过程拆成一个个方法&#xff0c;通过一个个方法的执行解决问题。面向对象会先抽象出对象&#xff0c;然后用对象执行方法的方式解决问题。 2.创建一个对象用什么运算符?对象实体与对象引用有何不同? n…

[C++]继承(续)

一、基类和派生类对象赋值转换 在public继承时&#xff0c;父类和子类是一个“is - a”的关系。 子类对象赋值给父类对象/父类指针/父类引用&#xff0c;我们认为是天然的&#xff0c;中间不产生临时对象&#xff0c;也叫作父子类赋值兼容规则&#xff08;切割/切片&#xff…