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

数据结构:堆的算法

目录

  • 一堆的向上调整算法
  • 二堆的向下调整算法
  • 三堆的应用:堆排序
  • 四TOPK问题

一堆的向上调整算法

我们在堆中插入一个数据一般实在堆的最后插入然后可以一步一步与上层结点(父结点进行比较),继而进行交换,完成二叉树的结构,

在这里插入图片描述
其中我们就有公式父节点的下标=(孩子结点的下标-1)/2就等价于parent=(child-1)/2

我们可以写一个方法让插入的数据与父结点进行比较直到合适的位置为止。

那么停下来就有两种情况:
1一直交换到头结点停下。2交换到合适的位置但没有到头结点,中途停下。

第一种情况一直到头结点,因为每次都要

child=parent;
parent = (child - 1) / 2;

所以当child到0没有父结点了就循环结束。

void AdjustUp(HeapType* a, int child) {int parent = (child - 1) / 2;while (child > 0) {if (a[child] < a[parent]){Swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}}}void Swap(HeapType* a, HeapType* b) {HeapType* tem = *a;*a = *b;*b = tem;}

第二种情况因为中点调整好了当if语句没交换时候就可以结束循环调整完成了

加上else
{
break;
}

void AdjustUp(HeapType* a, int child) {int parent = (child - 1) / 2;while (child > 0) {if (a[child] < a[parent]){Swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}}

二堆的向下调整算法

当我们要去删除一个大堆或者小堆的头结点的时候我们可以直接把尾部结点的数据和头部的交换,然后把访问下标的数字-1.然后进行向下调整,这样就可以建立二叉树的结构了

但是 我们有一个问题,我们都知道parent=(child-1)/2,且有唯一一个父节点。但是我们让头结点进行向下调整的时候要去交换哪个孩子结点呢?是否要判断?

在这里插入图片描述

如图这是个小堆,头结点进行向下调整的时候需要判断跟哪个孩子交换,必须保证是次小的孩子,要不然就会出现父节点比孩子结点大,就不是小堆了。大堆也是同样道理

判断代码如下

if (child + 1 < n && a[child] > a[child + 1]) {child = child + 1;

其中n是有效数据个数,需要保证有两个孩子才能判断
向下调整算法代码如下

void AdjustDown(HeapType* a, int parent, int n) {int child = parent * 2 + 1;while (child < n){if (child + 1 < n && a[child] > a[child + 1]) {child = child + 1;}if (a[parent] > a[child]) {Swap(&a[parent], &a[child]);parent = child;child = child * 2 + 1;}else{break;}}}

三堆的应用:堆排序

那么我们可以通过堆的结构来进行排序,因为二叉树不是严格意义上的顺序结构它只保证父节点比孩子结点大或小。
我们可以实现一个算法来把堆的二叉树结构调整为升序或者降序。

具体实现方法为,循环把头结点和尾结点进行交换,因为头结点是一个结构最大或者最小的,这时候我们把尾部结点减少一个,在进行向下调整,然后再进行交换,把次大或次小的数据放到最后一个,尾部结点减少一个,向下调整…如此循环直到到最后一个数据向下调整。这样就变成有序的了。
因为大堆的头结点是最大的,一开始放到尾结点,这样就是升序,反之小堆调整则为降序。

HeapSort2(a1, 6);
int sz = sizeof(a1) / sizeof(a1[0]);
for (int i = 0; i < sz; i++) {printf("%d ",a1[i]);
}
void HeapSort2(HeapType* arr, int n) {//进行向下调整建堆for (int i = (n - 1 - 1) / 2; i >= 0; i--) {AdjustDown(arr, i, n);}int end = n - 1;for (int i = end; i > 0; i--) {//小堆进行调整为降序Swap(&arr[0], &arr[end]);AdjustDown(arr, 0, end);end--;}
}

在这里插入图片描述

四TOPK问题

我们在N个数据中找前topk大或者小的数据这类问题一般思路就是一个个进行比较,这样空间复杂度太大。

我们可以先建立一个大小为k的堆,然后通过后N-k个数据依次和堆的头结点进行比较,判断是否入堆,如果入堆就向下调整到合适位置,这样数据读完我们就可以销毁文件,那么空吉安复杂度则只有建立的堆,然后堆的数据即为topk.

我们可以进行文件输入输出流来实现创造 N个数据
中间利用time函数,利用写的方式把数据写道date,txt文件中
大小为不大于等于1000000

void CreateNDate()
{// 造数据int n = 10000;srand(time(0));const char* file = "data.txt";FILE* fin = fopen(file, "w");if (fin == NULL){perror("fopen error");return;}for (size_t i = 0; i < n; ++i){int x = rand() % 1000000;fprintf(fin, "%d\n", x);}fclose(fin);
}

然后读取数据,建立k个大小的堆,再把文件后面数据和堆顶比较,如果比堆顶大就进堆,然后向下调整。

void PrintTopK() {int k = 0;printf("请输入");scanf("%d",&k);const char* file = "data.txt";FILE* fout = fopen(file, "r");if (fout == NULL) {perror("error");}HeapType* pp = (HeapType*)malloc(k * sizeof(HeapType));for (int i = 0; i < k; i++) {fscanf(fout, "%d", &pp[i]);}for (int i = (k - 1 - 1) / 2; i >= 0; i--) {AdjustDown(pp, i, k);}int x=0;while (fscanf(fout, "%d", &x) != EOF) {if (x > pp[0]) {pp[0] = x;AdjustDown(pp, 0, k);}}for (int i = 0; i < k;i++)  {printf("%d ", pp[i]);}fclose(fout);}

我们为了验证对不对可以修改两个数超过1000000,然后输出看对不对
最后输出结果

在这里插入图片描述

在这里插入图片描述

相关文章:

数据结构:堆的算法

目录 一堆的向上调整算法二堆的向下调整算法三堆的应用:堆排序四TOPK问题 一堆的向上调整算法 我们在堆中插入一个数据一般实在堆的最后插入然后可以一步一步与上层结点&#xff08;父结点进行比较&#xff09;&#xff0c;继而进行交换&#xff0c;完成二叉树的结构&#xff0…...

python画图|3D直方图基础教程

前述已经完成了直方图和3D图的基本学习&#xff0c;链接如下&#xff1a; 直方图&#xff1a;python画图|水平直方图绘制-CSDN博客 3D图&#xff1a;python画图|水平直方图绘制-CSDN博客 现在我们尝试把二者结合&#xff0c;画3D直方图。 【1】官网教程 首先&#xff0c;依…...

C语言中的函数,实参,形参,递归

1&#xff1a;什么是函数 2&#xff1a;定义带形式参数的函数和带实际参数的函数 3&#xff1a;递归 --------------------------------------------------------------------------------------------------------------------------------- 1&#xff1a;在 C 语言中&…...

ICM20948 DMP代码详解(15)

接前一篇文章&#xff1a;ICM20948 DMP代码详解&#xff08;14&#xff09; 上一回开始对icm20948_sensor_setup函数中第3段代码即inv_icm20948_initialize函数进行解析。为了便于理解和回顾&#xff0c;再次贴出其源码&#xff0c;在EMD-Core\sources\Invn\Devices\Drivers\IC…...

NC 和为K的连续子数组

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 描述 给定一个无序…...

JS设计模式之装饰者模式:优雅的给对象增添“魔法”

引言 在前端开发中&#xff0c;我们经常会遇到需要在不修改已有代码的基础上给对象添加新的行为或功能的情况。而传统的继承方式并不适合这种需求&#xff0c;因为继承会导致类的数量急剧增加&#xff0c;且每一个子类都会固定地实现一种特定的功能扩展。 装饰者模式则提供了…...

准备好了吗?JAVA从业AI开发的学习路线详解

作为一个拥有扎实 Java 基础的人&#xff0c;想要涉足人工智能&#xff08;AI&#xff09;应用开发&#xff0c;你已经在编程能力方面打下了很好的基础。Java 是一种通用的、强类型的语言&#xff0c;非常适合于开发高性能的应用程序&#xff0c;尤其是在后端服务和大规模分布式…...

神经网络通俗理解学习笔记(1)

神经网络通俗理解学习笔记&#xff08;1&#xff09; 神经网络原理激活函数前向传播和反向传播多层感知机代码实现加载数据网络结构损失函数优化器训练测试保存 回归问题一元线性回归多元线性回归多项式回归 线性回归代码实现数据生成设置超参数初始化参数可视化Pytorch模型实现…...

有n个人,他们需要分配m元钱(m>n),每个人至少分到1元钱,且每个人分到的钱数必须是整数。请问有多少种分配方案?

分配方案 描述 有n个人&#xff0c;他们需要分配m元钱(m>n)&#xff0c;每个人至少分到1元钱&#xff0c;且每个人分到的钱数必须是整数。请问有多少种分配方案? 输入 一行&#xff0c;两个整数&#xff0c;分别是人数n与钱数m&#xff0c;用一个空格隔开。 输出 一行&am…...

光耦——创新引擎 助推中国经济高质量发展

近年来&#xff0c;中国经济正处于转型升级的关键时期&#xff0c;高质量发展成为经济发展的重要目标。在这一伟大征程中&#xff0c;光耦作为一种关键性的电子元器件&#xff0c;正在发挥着重要的作用&#xff0c;助力中国经济迈向更加光明的未来。 光耦概念及工作原理 ▲光耦…...

Go 中 RPC 的使用教程

前言 RPC&#xff08;Remote Procedure Call&#xff09;是一种允许程序调用远程服务器上函数的方法&#xff0c;调用过程对于开发者来说像是调用本地函数一样方便。Go 语言自带了强大的 net/rpc 库&#xff0c;能够让开发者轻松实现基于 Go 的 RPC 服务。本文将介绍 Go 中 RP…...

挖耳勺可以伸进耳朵多深?安全可视挖耳勺推荐!

一般来说&#xff0c;挖耳勺不应该伸进耳朵太深&#xff0c;外耳道的长度大约在2.5厘米到3.5厘米之间&#xff0c;但不建议将挖耳勺伸进超过外耳道外1/3的深度&#xff0c;也就是大概1厘米左右较为安全。因为如果伸得太深&#xff0c;很容易损伤外耳道皮肤&#xff0c;引起疼痛…...

SuperMap GIS基础产品FAQ集锦(20240911)

一、SuperMap iObjects Java 问题1&#xff1a;【iObject Python】Objects Python产品有哪些能力特性和优势&#xff1f; 11.2.0 【解决办法】iObjects Python产品包含传统GIS功能&#xff08;基于iObjects Java扩展的功能接口&#xff09;和AI GIS功能模块。 其中传统GIS功能…...

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compo…...

ChatGPT提示词优化大师使用指南

我希望你成为我的ChatGPT提示词优化大师。 您的目标是帮助我根据自己的需要制定尽可能最好的提示。 你提供的提示应该是站在我向ChatGPT发起请求的角度来写的。我的初始提示词如下&#xff1a;此处填入你的初始提示词 ChatGPT提示词生成器 我希望你充当提示词生成器。 比如&…...

计算机毕业设计 智能推荐旅游平台 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…...

【拥抱AI】基于多种数据分段工具的优缺点分析

最近在深入了解RAG方面的知识&#xff0c;其中数据清洗和数据分段是创建知识库的重要步骤。数据清洗目前暂时选用了MinerU&#xff0c;然后就需要针对数据分段进行选型。 以下是我了解到的几种数据分段工具&#xff0c;简单总结了一下它们的优缺点&#xff0c;权当笔记分享&am…...

在 Windows 系统上,文件传输到虚拟机(VM)可以通过 VS Code 的图形界面(GUI)或命令行工具进行操作

在 Windows 系统上&#xff0c;文件传输到虚拟机&#xff08;VM&#xff09;可以通过 VS Code 的图形界面&#xff08;GUI&#xff09;或命令行工具进行操作。以下是几种方法&#xff1a; ### 方法 1: 使用 VS Code 图形界面 1. **连接到远程 VM**&#xff1a; - 在 VS Cod…...

kafka的主要功能

Apache Kafka 是一个分布式流处理平台&#xff0c;它最初由 LinkedIn 开发&#xff0c;后来捐赠给了 Apache Software Foundation&#xff0c;并成为了 Apache 的顶级项目。Kafka 设计用于处理实时数据流&#xff0c;并且提供了高性能、可扩展性和持久性。下面是 Kafka 的主要功…...

vue3中provide和inject详解

provide和inject是什么 provide 和 inject 是 Vue.js 框架中提供的一种依赖注入机制。这种机制允许一个祖先组件&#xff08;提供者&#xff09;向其所有子孙组件&#xff08;使用者&#xff09;提供数据或方法&#xff0c;而不需要通过逐层组件传递属性&#xff08;props&…...

从拖拽到对话:衡石Agentic BI如何重构企业数据分析的交互范式

传统BI的交互困局在商业智能发展史上,2025年或许会被标记为一个转折点。这一年,衡石科技发布的HENGSHI SENSE 6.0 Agentic BI平台,标志着数据分析从"被动工具"正式迈入"主动智能体"时代。过去二十年,"拖拽生成报表"一直被奉为BI工具的黄金标准。…...

CentOS7下StarRocks 3.1.13集群部署实战:三节点FE高可用配置详解

CentOS7下StarRocks 3.1.13集群部署实战&#xff1a;三节点FE高可用配置详解 在当今数据驱动的商业环境中&#xff0c;企业级分析型数据库的可靠性和性能至关重要。StarRocks作为新一代MPP分析数据库&#xff0c;凭借其卓越的实时分析能力和高并发查询性能&#xff0c;正逐渐成…...

4步精通Logisim-evolution:面向数字工程师的开源电路设计工具指南

4步精通Logisim-evolution&#xff1a;面向数字工程师的开源电路设计工具指南 【免费下载链接】logisim-evolution Digital logic design tool and simulator 项目地址: https://gitcode.com/gh_mirrors/lo/logisim-evolution Logisim-evolution作为一款开源的数字逻辑设…...

XCOM 2模组管理的终极解决方案:Alternative Mod Launcher完整指南

XCOM 2模组管理的终极解决方案&#xff1a;Alternative Mod Launcher完整指南 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/g…...

嵌入式WiFi开发 | 基于wireless_tools的交叉编译实战与移植指南

1. 嵌入式WiFi开发入门&#xff1a;为什么需要wireless_tools&#xff1f; 在嵌入式Linux开发中&#xff0c;网络连接能力往往是刚需。想象一下你的智能家居设备需要自动连接路由器&#xff0c;或者工业传感器需要通过WiFi上传数据——这些都离不开可靠的无线网络配置工具。这就…...

DLSS Swapper:智能管理游戏DLSS版本,轻松优化画质与性能

DLSS Swapper&#xff1a;智能管理游戏DLSS版本&#xff0c;轻松优化画质与性能 【免费下载链接】dlss-swapper 项目地址: https://gitcode.com/GitHub_Trending/dl/dlss-swapper DLSS Swapper是一款专为NVIDIA显卡用户设计的智能DLSS动态链接库管理工具&#xff0c;能…...

OpenClaw超轻量方案:nanobot镜像对接QQ机器人全流程

OpenClaw超轻量方案&#xff1a;nanobot镜像对接QQ机器人全流程 1. 为什么选择nanobot镜像 去年夏天&#xff0c;我在尝试将OpenClaw接入QQ机器人时遇到了不少麻烦。当时需要分别部署模型服务、配置OpenClaw网关、调试QQ机器人接口&#xff0c;整个过程耗费了整整三天时间。直…...

Z-Image-GGUF小程序开发:微信小程序前端调用云端AI绘画API

Z-Image-GGUF小程序开发&#xff1a;微信小程序前端调用云端AI绘画API 最近在折腾AI绘画&#xff0c;发现一个挺有意思的事儿&#xff1a;很多厉害的模型都部署在云端服务器上&#xff0c;但咱们平时用手机的时间可比用电脑多多了。要是能在微信里随手打开一个小程序&#xff…...

Minikube国内环境配置全攻略:从安装到Dashboard镜像加速(含阿里云镜像源)

Minikube国内环境高效配置指南&#xff1a;从零搭建到Dashboard可视化 对于国内开发者而言&#xff0c;在本地环境中快速搭建Kubernetes学习平台往往面临镜像拉取缓慢甚至失败的困扰。本文将系统性地介绍如何利用Minikube在国内网络环境下构建稳定的单机Kubernetes环境&#xf…...

效率飙升秘籍:用快马生成全自动opencode安装与配置工具

最近在折腾opencode的安装配置&#xff0c;发现手动操作实在太费时间了——要查文档、装依赖、配环境变量&#xff0c;一不小心就踩坑。后来发现用InsCode(快马)平台可以快速生成自动化脚本&#xff0c;效率直接翻倍。今天就把这个"偷懒"方案分享给大家。 环境预检查…...