数据结构—堆(C语言实现)

news2024/12/26 11:55:53

目录

堆是什么?

一、大堆

一、小堆

如何实现堆?

代码实现 ?

一、定义堆的结构体

二、初始化堆

三、构建堆

1.利用向下调整算法

2.开始构建

四、插入元素

1.利用向上调整算法

五、取出堆顶元素、销毁堆

六、堆排序

Extra:TOP K 问题


堆是什么?

 堆是数据结构的一种,它的逻辑结构是一个完全二叉树,存储结构是一个数组。

一、大堆

 每个父节点都大于子节点

一、小堆

每个父节点都小于子节点

如何实现堆?

数组即可,利用完全二叉树的特点。(后面将不断用到)

 

代码实现 ?

一、定义堆的结构体

typedef int E;
typedef struct my_heap {
	E* _heap;
	int _size;
	int _capacity;
}my_heap;

二、初始化堆

void initiaze(my_heap* heap, E* arry, int n) {
	assert(arry);
	assert(heap);
	heap->_heap = (E*)malloc(n * sizeof(E));
	assert(heap);
	heap->_capacity = n;
	heap->_size = n;
	memcpy(heap->_heap, arry, n * sizeof(E));//内存拷贝
}

三、构建堆

1.利用向下调整算法

//小堆-向下调整算法
void heap_down(my_heap* heap,int root) {
	int parent = root;
	int child = parent * 2 + 1;
	while(child<heap->_size){
	if (child + 1 <heap->_size && heap->_heap[child + 1] < heap->_heap[child]) {
		 child++;
	}
	if (heap->_heap[child] < heap->_heap[parent]) {
		swap(&(heap->_heap[child]), &(heap->_heap[parent]));
		parent = child;
		child = child * 2 + 1;
	}
	else {
		break;
	}
	}
}
2.开始构建

 会向下调整算法还不够,向下调整算法只能用于左右子树都已经是堆的情况下。

而如何使每一颗左右子树都是堆,需要从最小不可拆分的节点开始,依次往前递推。

每次对这些节点使用向下调整算法,

//堆建立-小堆
void com_heap(my_heap* heap) {
	assert(heap);
	int i =0;
	for (i= (heap->_size - 2) / 2; i >= 0; i--) {
		heap_down(heap, i);
	}
}

四、插入元素

 

要保持小堆,除了可以用上面构建堆的方法,重新构建一次,但这样时间复杂度就太高了,这时就需要向上调整算法了。

1.利用向上调整算法

 

//向上调整算法 
void heap_up(my_heap* heap,int child){
	assert(heap);
	int parent =  (child-1)/2;
	while(child>0){
		if(heap->_heap[child]<heap->_heap[parent]){
			swap(&(heap->_heap[child]), &(heap->_heap[parent]));
			child=parent;
			parent=(child-1)/2;
		}else{
			break;
		}
	}
}
//往堆中添加元素
void heap_push(my_heap* heap,E ele){
	assert(heap);
	//如果空间不够扩容,每次扩容为上次容量的两倍
	if(heap->_size==heap->_capacity+1){
		heap->_capacity *=2;
		heap->_heap=realloc(heap,heap->_capacity*(sizeof(E)));
		if(!heap)return;
	}
	heap->_heap[heap->_size++]=ele;
	heap_up(heap,heap->_size-1);
}

五、取出堆顶元素、销毁堆

//从堆中取出元素,取出堆顶元素
E heap_hatch(my_heap* heap) {
	assert(heap);
	return heap->_heap[0];
}
//堆销毁
void heap_destroy(my_heap* heap) {
	assert(heap);
	free(heap->_heap);
	heap->_heap = NULL;
}

六、堆排序

前面我们已经了解了构造堆,插入元素,如果要把这个数组的数从小排到大,能否使用堆来进行呢。

首先,我们要明白升序要大堆,降序要小堆。(后面解释)

 

 这就是堆排序的思想,不断拿到堆顶元素,放到数组最后,得到最小、第二小、第三小......的数字,实现降序,你也知道了为什么要使用大堆排升序,小堆排降序。

下面是升序代码:

//堆排序-升序
E* heap_sort(int *arry,int len) {
	//建大堆
	assert(arry);
	if (len == 0)return NULL;
	my_heap heap;
	initiaze(&heap, arry, len);
	com_heap_big(&heap);
	//堆建好后,每次把堆最后一个元素与堆顶替换,再将堆大小减一,进行向下调整算法
	int start = 0;
	int end = len - 1;
	while (end) {
		swap(heap._heap + end, heap._heap + start);
		end--;
		heap._size--;
		heap_down_big(&heap, 0);
	}
	memcpy(arry, heap._heap, len*(sizeof(E)));
	heap_destroy(&heap);
	return arry;
}

Extra:TOP K 问题

要求:从N个数中找到最小或最大的前k个数

 

相信你已经会了,那么要求最小的k个数就需要建立一个k个元素的大堆了。 

//topk问题-最大k个数
int* top_k(int* arry,int len,int k) {
	assert(arry);
	//选数组前k个数组成k个元素的堆
	int* heap_k = (int*)malloc(k * sizeof(int));//因为要把数组传出去,动态开辟
	memcpy(heap_k, arry, k * sizeof(int));
	//构建堆
	my_heap heap;
	heap._heap = heap_k;
	heap._size = k;
	heap._capacity = k;
	com_heap(&heap);
	//依次拿堆顶元素与数组从k开始的元素进行比较
	for (int i = k; i < len; i++) {
		if (heap._heap[0] < arry[i]) {
			swap(heap._heap + 0, arry + i);
			//向下调整
			heap_down(&heap, 0);
		}
	}
	//此时heap里面的元素就是最大的k个数了
	return heap._heap;
}

 

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

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

相关文章

SpringBoot中xml映射文件

1.规范 说明&#xff1a;XML映射文件的名称与Mapper接口名称一致&#xff0c;并且将XML映射文件和Mapper接口放置在相同包下&#xff08;同包同名&#xff09;。 xML映射文件的namespace属性为Mapper接口全类名一致。 XML映射文件中sql语句的id与Mapper接口中的方法名一致&…

Spring面试题4:面试官:说一说Spring由哪些模块组成?说一说JDBC和DAO之间的联系和区别?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:说一说Spring由哪些模块组成? Spring是一个开源的Java框架,由多个模块组成,每个模块都提供不同的功能和特性。下面是Spring框架的主要模块: S…

基于nodejs+vue办公OA公文发文件管理系统

论文的研究内容包括&#xff1a;公文分类、公文信息、待办提醒等方面进行了研究。系统以当前应用最为广泛的nodejs语言为基础&#xff0c;结合了目前应用最为广泛的嵌入式嵌入式平台&#xff0c;集成了B/S体系结构。数据库选择简便高效的MySQL&#xff0c;vue框架。在OA公文发文…

大语言模型之十 SentencePiece

Tokenizer 诸如GPT-3/4以及LlaMA/LlaMA2大语言模型都采用了token的作为模型的输入输出&#xff0c;其输入是文本&#xff0c;然后将文本转为token&#xff08;正整数&#xff09;&#xff0c;然后从一串token&#xff08;对应于文本&#xff09;预测下一个token。 进入OpenAI官…

【LeetCode75】第六十三题 不同路径

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 题目给我们返回地图的长和宽。问我们从地图的左上走到右下有几种方法。我们只能往下走或是往右走。 这个算是简单的二维动态规划题了。 …

Docker安装 MySQL8.0.33

Docker 核心&#xff1a;容器 Container 和镜像 Images Docker 安装镜像 mysql:8.0.33 图形化安装界面可选择版本较少 推荐使用命令行安装(可以自定义安装的版本) 版本安装命令链接&#xff1a;mysql Tags | Docker Hub 终端执行命令 docker pull mysql:8.0.33创建容器 安装完…

多维时序 | MATLAB实现WOA-CNN-BiGRU-Attention多变量时间序列预测(SE注意力机制)

多维时序 | MATLAB实现WOA-CNN-BiGRU-Attention多变量时间序列预测&#xff08;SE注意力机制&#xff09; 目录 多维时序 | MATLAB实现WOA-CNN-BiGRU-Attention多变量时间序列预测&#xff08;SE注意力机制&#xff09;预测效果基本描述模型描述程序设计参考资料 预测效果 基本…

【Hello Linux】高级IO Select

本篇博客介绍&#xff1a;介绍Linux中的高级IO 高级IO IO五种IO模型非阻塞IO如何判断异常读取 IO多路转接之Selectselect的优缺点 网络通信的本质其实就是一种IO 而我们知道的是 IO的效率实际上是十分低下的 所以说我们需要一些机制或者方法来解决这个效率问题 IO IO实际上…

R and RStudio的安装教程【2023】

首先需要安装R&#xff0c;才能安装RStudio。 安装包文末获取或者去官网获取&#xff0c;一样的&#xff1a; R的安装&#xff1a;&#xff08;很简单&#xff0c;如果你想安装到C盘&#xff0c;全部选项无脑选下一步&#xff0c;不想安装到C盘&#xff0c;就改一下就ok.&…

软件测试同行评审到底是什么?

【软件测试面试突击班】如何逼自己一周刷完软件测试八股文教程&#xff0c;刷完面试就稳了&#xff0c;你也可以当高薪软件测试工程师&#xff08;自动化测试&#xff09; “同行评审是一种通过作者的同行(开发、测试、QA等)来确认缺陷和需要变更区域的检查方法。”在软件测试中…

五、C#—字符串

&#x1f33b;&#x1f33b; 目录 一、字符串1.1 字符类型1.2 转义字符1.3 字符串的声明及赋值1.3.1 c# 中的字符串1.3.2 声明字符串1.3.3 使用字符串1.3.4 字符串的初始化1.3.4.1 引用字符串常量之初始化1.3.4.2 利用字符数组初始化1.3.4.3 提取数组中的一部分进行初始化 1.3.…

企业微信自建小程序应用踩坑实践

最近开发了一个小程序接入企业微信的需求&#xff0c;企业微信的权限限制诸多&#xff0c;网上的完整示例又少之又少&#xff0c;因此踩了比较多坑&#xff0c;与大家分享。 开发调试 在开发者工具中如果直接使用微信小程序模式&#xff0c;调用wx.qy接口会提示不存在&#x…

Qt5开发及实例V2.0-第二十一章-Qt.Quick Controls开发基础

Qt5开发及实例V2.0-第二十一章-Qt.Quick Controls开发基础 第21章 Qt Quick Controls开发基础21.1 Qt Quick Controls概述21.1.1 第一个Qt Quick Controls程序21.1.2 Qt Quick窗体应用程序的构成 21.2 Qt Quick控件21.2.1 概述21.2.2 基本控件21.2.3 高级控件21.2.4 样式定制 2…

光电开关-NPN-PNP

基础概念 有信号 “检测到物体/有物体遮挡” 工作原理 NPN&#xff1a;表示共正电压&#xff0c;输出负电压【只能输出低电压或者悬空 常开常闭是指 输出有没有跟“地”接通】&#xff1b; NPN NO&#xff1a;表示常态下是常开的&#xff0c;检测到物体时黑色线输出一个负电压…

docker jira 一键安装含PJ(docker 一键安装jira)

docker jira 一键安装含PJ&#xff08;docker 一键安装jira&#xff09; 本文仅供参考学习&#xff0c;请勿用于商业用途本文用于Jira在Docker的安装&#xff0c;仅用于记录安装方式转载请注明来源Linux安装可参考链接Windows安装可查考链接Docker一键安装Confluence PJ条件允…

配置HBase和zookeeper

一、上传文件 二、解压 tar -zxf ./zookeeper-3.4.5-cdh5.14.2.tar.gz -C /opt/soft/ tar -zxf ./hbase-2.3.5-bin.tar.gz -C ../soft/ 三、改名字 mv ./zookeeper-3.4.5-cdh5.14.2/ zk345 mv ./hbase-2.3.5/ hbase235 四、配置映射 vim /etc/profile#ZK export ZOOKEEPE…

pytorch学习------实现手写数字识别

目录 目标一、思路和流程分析二、准备训练集和测试集2.1、图形数据处理方法2.1.1、torchvision.transforms.ToTensor2.1.2、torchvision.transforms.Normalize(mean, std)2.1.3、torchvision.transforms.Compose(transforms) 2.2、准备MNIST数据集的Dataset和DataLoader三、构建…

NodeRed拖拉拽实现OPCUA数据订阅,发布至MQTT并落库MySQL

背景 几年前曾根据 Node-Red 官网示例进行了简单的体验&#xff0c;当时觉得这东西就是个玩具&#xff0c;拿过来玩一玩可以&#xff0c;不实用&#xff1b;但是如今发现有不少产品对其进行了集成&#xff0c;并做出了复杂的商业应用&#xff0c;这确实是极大的震撼。 使用看似…

Vulnhub系列靶机---JANGOW 1.0.1

文章目录 网卡配置信息收集主机发现端口扫描 漏洞利用反弹Shell提权 靶机文档&#xff1a;JANGOW 1.0.1 下载地址&#xff1a;Download (Mirror) 难易程度&#xff1a;. 网卡配置 水果味儿 信息收集 主机发现 端口扫描 访问80端口 点击site目录 点击页面上方的一个选项&…

【跟小嘉学习区块链】一、区块链基础知识与关键技术解析

系列文章目录 【跟小嘉学习区块链】一、区块链基础知识与关键技术解析 文章目录 系列文章目录[TOC](文章目录) 前言一、区块链基础1.1、区块链的来龙去脉1.1.1、区块链技术起源1.1.2、核心技术发展脉络 1.2、比特币产生的背景与现状1.2.1、现行货币体系存在的问题1.2.2、数字货…