数据结构之堆详解

news2024/11/26 15:29:08

目录

1.什么是堆

堆的定义

结构体定义与函数接口

堆的初始化

堆的销毁

入堆

向上调整算法

大堆

出堆

向下调整算法

返回堆顶元素

判空

堆的应用


1.什么是堆

知道以上的存储方法,对于完全二叉树,有一个叫做堆的结构,堆本质就是一个完全二叉树,

堆分两种:1.大堆    2.小堆

除了是完全二叉树,大堆需满足任何一个双亲都大于等于孩子,对于小堆,任何一个双亲都小于等于孩子。

堆的定义

我们实现堆就用数组来实现的:这里以实现小堆为例

结构体定义与函数接口

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int HPDATAtype;
typedef struct Heap
{
	HPDATAtype *a;
	int size;
	int capacity;
}HP;

void Heapinit(HP* f);
void Heapdestroy(HP* f);
void Heappop(HP* f);
void Heappush(HP* f , HPDATAtype x);

堆的初始化

void Heapinit(HP* f)
{
	//初始有4个空间
	assert(f);
	f->a = NULL;
	f->size = 0;
	f->capacity = 0;
}

堆的销毁

void Heapdestroy(HP* f)
{
	assert(f->a);
	free(f->a);
	f->a = NULL;
}

入堆

void Heappush(HP* f, HPDATAtype x)
{
	assert(f);
	if (f->capacity == f->size)
	{
	int  newcapacity = f->capacity = 0 ? 4 : f->capacity*2;
      HPDATAtype* newnode = (HPDATAtype*)malloc(newcapacity);
	if (newnode == NULL)
	{
		perror("扩容失败\n");
		return;
	}
	f->a = newnode;
	f->capacity = f->capacity*2;
	}
	f->a[f->size] = x;
	f->size++;
	//向上调整算法
	Adjustup(f->a, f->size - 1);
	//向下调整算法
	//Adjustdown(f->a, f->size - 1);
}

在这里在入堆之后,也就是元素赋值到数组之后,根据你对数组的调整,也就是所说的向上调整算法,和向下调整算法,决定是小堆,还是大堆。

向上调整算法

我们这里通过对树所对应的数组元素的关系寻找父亲。 小堆:

void Adjustup(HPDATAtype*a, int child)
{
	//根据孩子zhaofuqin
	int parent = (child - 1) / 2;
	while (child>0)
	{
		if ( a[child]<a[parent])
		{
		  HPDATAtype p = a[child];
		  a [child] = a[parent];
		  a[parent]=p;

		  child = parent;
		  parent = (child - 1) / 2;
		}
		else 
		{
			break;
		}
		
	}
}

大堆

这里只需要更改判断条件就变成大堆的调整

void Adjustdown(HPDATAtype* a, int child)
{
	//根据孩子找父亲
	int parent = (child - 1) / 2;
	while (child > 0)
	{
		if (a[child] > a[parent])
		{
			int tmp = a[child];
			a[child] = a[parent];
			a[parent] = tmp; 

        child = parent;
		parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
		

	}

}

出堆

出堆就是最后一个元素换到第一个元素,在size--,之后在进行调整。


void Heappop(HP* f){
	assert(f);
	//堆顶元素出堆,最后元素出堆
	assert(f->size);
	int tmp = f->a[0];
	f->a[0] = f->a[f->size - 1];
	f->a[f->size - 1] = tmp;
	f->size--;
	//向下调整
	Adjustdown(f->a, f->size, 0);
};

向下调整算法

出堆为了不改变原有的父节点与兄弟节点的关系,采用的是将堆底的最后一个与第一个互换,在减减,此时我们仍需要调整堆,采用向下调整算法---即从第一个节点处开始,找作为父节点的儿子节点中较小的那一个,两者比较,循环调整。

因此传参需要堆的大小以及第一个父亲结点坐标也就是0.

void Adjustdown(HPDATAtype* a, int size,int parent)
{
	int child =parent * 2 +1;
	while (child<size)
	{
		if ((child+1<size)&&a[child + 1] < a[child])//若右孩子存在且小于左孩子
		{
			++child;
		}
		if (a[child] < a[parent])
		{
			//交换
			int tmp = a[child];
			a[child] = a[parent];
			a[parent] = tmp;

			parent = child;
			child = parent * 2 + 1;
		}else
		{
			break;
		}
	}

}

返回堆顶元素

HPDATAtype HeapTop(HP* f)
{
	assert(f);
	assert(!HeapEmpty(f));

	return f->a[0];//返回堆顶数据
}

判空

bool HeapEmpty(HP* f)
{
	if (f->size == 0)
	{
		return true;
	}
	else
	{
		return false;
	}
}

堆的应用

.堆可以用作优先级队列,实现高效的插入和删除操作


.堆可以用来解决海量数据的topk问题,即从大量数据中找出最大或最小的k个数


.堆可以用来进行堆排序,即每次把堆顶元素和堆尾元素交换,然后重新调整堆,直到堆为空


.堆还可以用来实现一些其他的算法,比如哈夫曼编码,Dijkstra算法等

需要注意的是对于向上排序算法还是向下排序算法,他们都是一对一对的使用,从而取决于你是大堆还是小堆,主要体现调整算法中的判断条件。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

内核调试工具crash使用

内核调试工具crash使用 前言初识获取vmlinuxDwarf Error: wrong version in compilation unit header (is 5, should be 2, 3, or 4) 其他 前言 在编写内核驱动的过程中&#xff0c;时不时就导致内核崩溃&#xff0c;也没啥好的调试方法&#xff0c;要么dmesg打印内核日志&…

socket | 网络套接字、网络字节序、sockaddr结构

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和…

量化论文学习之《基于 CNN-LSTM 混合模型的股价 预测》

主要原理 CNN-LSTM 混合模型首先使用 CNN 来提取时间序列数据的特征&#xff0c;然 后将特征输入进 LSTM 模型中来进行下一交易日股票收盘价的预测。 数据处理 使用数据 作者发现加入volume,pctChg后效果变差&#xff0c;可能原因是加入了相关性较低的特征后造成了数据冗余…

Ubuntu挂载阿里云盘

目录 所需环境安装docker安装rclone获取阿里云盘token 获取docker镜像并运行获取本机IP信息总结rclone配置挂载网盘到本地文件夹开机启动 所需环境 安装docker 使用官方脚本进行全自动安装 curl -fsSL https://test.docker.com -o test-docker.shsudo sh test-docker.sh安装r…

Spring Boot 可执行 Jar 包运行原理

Spring Boot 有一个很方便的功能就是可以将应用打成可执行的 Jar。那么大家有没想过这个 Jar 是怎么运行起来的呢&#xff1f;本篇博客就来介绍下 Spring Boot 可执行 Jar 包的运行原理。 打可执行 Jar 包 将 Spring Boot 应用打成可执行 Ja r包很容易&#xff0c;只需要在 p…

数字信号处理基础(一):常用信号产生

目录 1. 写在前面2. 连续信号和离散信号2.1连续信号2.2 离散信号 3. 常用信号的产生3.1 单位脉冲序列3.2 单位阶跃序列3.3 指数函数3.4 正弦信号和余弦信号3.5 sinc函数3.6 矩形脉冲信号 4. 信号卷积5. 完整代码 1. 写在前面 为了更好的理解通信原理系列文章&#xff0c;在此补…

28 SQL——表子查询

create table dept(id int primary key auto_increment,name varchar(15))comment 部门;insert into dept(id, name) values (1,研发部),(2,市场部),(3,财务部),(4,销售部),(5,总经办),(6,人事部);create table staff (id int primary key auto_increment commentID,name …

使用Mathtype公式编辑器生成CSDN中的数学公式

使用Mathtype公式编辑器生成CSDN中的数学公式 在CSDN中输入数学公式&#xff0c;直接使用LaTeX编辑输入公式有一些难度&#xff0c;如果你熟悉Mathtype公式编辑器&#xff0c;那么在CSDN文档中输入数学公式也变的相对容易。 下面我们举例说明使用Mathtype转换输入CSDN的公式。…

Weex工具链的奥秘

在2017年1月12日 Weex Conf 2017上&#xff0c;来自阿里的卜道依据Weex开发中的痛点介绍了Weex的打包和插件机制&#xff0c;同样来自阿里的归影介绍了Weex的调试工具Devtools&#xff0c;共同揭秘了Weex的工具链。本文是卜道和归影关于Weex工具链实践的分享整理。 Weexpack与…

MyBatis各种类型查询数据的数据绑定

文章目录 1、前言2、查询一个实体类对象字段名和属性名无法映射处理方式一&#xff1a;起别名方式二&#xff1a;使用全局配置文件配置映射规则方式三&#xff1a;自定义resultmap 3、查询一个list集合4、查询单个数据5、查询一条数据为map集合6、 查询多条数据为map集合方式一…

Python中使用Scipy模块中root函数求解非线性方程的解法举例

Python中使用Scipy模块中root函数求解非线性方程的解法举例 Python中的SciPy模块功能强大&#xff0c;下面举例说明使用该模块求解非线性方程或非线性方程组。在求解时候&#xff0c;用到scipy.optimize模块中的root函数。 1.root函数的调用格式 调用它们的格式为 from scipy…

使用MinIO文件存储系统【完成视频断点续传】业务逻辑

目录 视频上传 接口一&#xff1a;检查该视频/媒资文件是否已经上传完成 接口二&#xff1a;检查视频分块是否已经在minio中已经存在 接口三&#xff1a;上传分块文件到minio中&#xff08;已经上传的分块会在接口二进行校验&#xff09; 接口四&#xff1a;合并上传的分块…

git生成密钥方法

1、密钥生成 打开Git Bash&#xff0c;查看ls ~/.ssh下是否有密钥文件id_rsa*&#xff0c;有的话可先进行备份。 然后用如下命令生成新密钥&#xff1a; ssh-keygen -t rsa -C "your_emailexample.com" 参数含义&#xff1a; -t 指定密钥类型&#xff0c;默认是 …

chatgpt赋能Python-pythonbif

Python Bif: 简介和使用指南 Python Bif是一种用于机器学习和数据科学的强大包。它提供了一些重要的功能&#xff0c;例如分类、集成和回归。这篇文章将向您介绍Python Bif的主要特性和如何使用它来完成各种数据科学任务。 什么是Python Bif&#xff1f; Python Bif是一个通…

Spring源码阅读:AOP原理

一、概述 以下便是Spring Aop的流程&#xff0c;下面我将一一介绍下面的各个方法。 下面是流程中的主要方法。 二、测试代码 下面我将写一个例子介绍Spring Aop的流程。 被增强类&#xff1a; public class MyCalculator {public Integer add(Integer i, Integer j) throw…

逼近GPT-4!BLOOMChat: 开源可商用支持多语言的大语言模型

背景 SambaNova和Together这2家公司于2023.05.19开源了可商用的支持多语言的微调模型BLOOMChat。 SambaNova这家公司专注于为企业和政府提供生成式AI平台&#xff0c;Together专注于用开源的方式打造一站式的foundation model&#xff0c;赋能各个行业。 OpenAI的GPT-4和Goo…

【将maven源改为国内阿里云镜像】

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 1. 如何配置Maven镜像&#xff1f; 2. Idea中m…

【Java入门】初识Java

前言 &#x1f4d5;作者简介&#xff1a;热爱跑步的恒川&#xff0c;致力于C/C、Java、Python等多编程语言&#xff0c;热爱跑步&#xff0c;喜爱音乐的一位博主。 &#x1f4d7;本文收录于Java入门篇系列&#xff0c;该专栏主要讲解&#xff1a;什么是java、java的数据类型与变…

MATLAB|004|MATLAB M-Files|MATLAB数据类型

MATLAB M-Files 我们一直强调MATLAB是一个功能强大的编程语言及交互式计算环境&#xff0c;之前学习的内容中&#xff0c;我们学会了在 MATLAB 命令提示符下输入命令&#xff0c;而且我们主要是把MATLAB环境作为一个计算器使用。其实&#xff0c;MATLAB 还允许写入到一个文件中…

5分钟掌握利用pycharm插件BitoAI 实现chatgpt自动编写代码

一、BitoAI 简介 最近出现了一款新型编程助手BitoAI。今天的主要内容就是给大家介绍它&#xff0c;号称 IDE 的“瑞士军刀”&#xff0c;可以提升开发 10 倍的效率。 简言之它的强大之处就是可以通过类似于ChatGPT对话的方式来编写代码&#xff0c;分析代码&#xff0c;生成代…