追梦之旅【数据结构篇】——详解小白如何使用C语言实现堆数据结构

news2025/1/20 3:53:09

详解小白如何使用C语言实现堆数据结构 + “痛”撕堆排序~😎

  • 前言🙌
  • 什么是堆?
    • 堆的概念及结构
  • 堆的性质:
    • 堆的实现
      • 堆向下调整算法
      • 画图分析:
        • 堆向下调整算法源代码分享:
          • 向下调整建小堆
          • 向下调整建大堆
        • 堆向上调整算法源代码分享:
        • 画图分析:
          • 向上调整建小堆
          • 向上调整建大堆
    • C语言整体实现堆数据结构源代码分享
      • 堆的插入:
      • 堆的删除:
        • 画图分析:
      • 头文件(Heap.h)编写:
      • 功能文件(Heap.c)编写:
      • 测试文件(test.c)编写:
      • 运行结果测试截图:
  • 总结撒花💞

追梦之旅,你我同行

   
😎博客昵称:博客小梦
😊最喜欢的座右铭:全神贯注的上吧!!!
😊作者简介:一名热爱C/C++,算法等技术、喜爱运动、热爱K歌、敢于追梦的小博主!

😘博主小留言:哈喽!😄各位CSDN的uu们,我是你的博客好友小梦,希望我的文章可以给您带来一定的帮助,话不多说,文章推上!欢迎大家在评论区唠嗑指正,觉得好的话别忘了一键三连哦!😘
在这里插入图片描述

前言🙌

    哈喽各位友友们😊,我今天又学到了很多有趣的知识现在迫不及待的想和大家分享一下!😘我仅已此文,手把手带领大家追梦之旅【数据结构篇】——详解小白如何使用C语言实现堆数据结构~ 都是精华内容,可不要错过哟!!!😍😍😍

什么是堆?

堆的概念及结构

如果有一个关键码的集合K = { , , ,…, },把它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中,并满足:

  1. 父结点的值都大于孩子结点的值,则称为大堆;
  2. 父结点的值都小于孩子结点的值,则称为小堆;
    大堆也称为大根堆,小堆也叫做小根堆。

堆的性质:

  • 堆中某个节点的值总是不大于或不小于其父节点的值;
  • 堆总是一棵完全二叉树。
    在这里插入图片描述

在这里插入图片描述

堆的实现

堆向下调整算法

现在我们给出一个数组,逻辑上看做一颗完全二叉树。我们通过从根节点开始的向下调整算法可以把它调整成一个小堆。向下调整算法有一个前提:左右子树必须是一个堆,才能调整

画图分析:

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

堆向下调整算法源代码分享:

向下调整建小堆
//向下调整--建小堆
void AdjustDown(int* 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])
		{
			Swap(&(a[parent]), &(a[child]));
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}


向下调整建大堆
//建大堆
void AdjustDown(int* 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])
		{
			Swap(&(a[parent]), &(a[child]));
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

堆向上调整算法源代码分享:

画图分析:

在这里插入图片描述

在这里插入图片描述

向上调整建小堆
void AdjustUp(HPDataType* a, int child)
{
	assert(a);
	while (child > 0)
	{
		int parent = (child - 1) / 2;
		if (a[child] < a[parent])
		{
			Swap(&(a[child]), &(a[parent]));
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}
向上调整建大堆
//向上调整建大堆
void AdjustUp(HPDataType* a, int child)
{
	assert(a);
	while (child > 0)
	{
		int parent = (child - 1) / 2;
		if (a[child] > a[parent])
		{
			Swap(&(a[child]), &(a[parent]));
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

C语言整体实现堆数据结构源代码分享

堆的插入:

先插入一个10到数组的尾上,再进行向上调整算法,直到满足堆。
在这里插入图片描述

void HeapPush(HP* php, HPDataType x)
{
	assert(php);
	//扩容
	if (php->capacity == php->size)
	{
		int newcapacity = php->capacity == 0 ? 4 : php->capacity * 2;
		HPDataType* tem = (HPDataType*)realloc(php->a, sizeof(HPDataType) * newcapacity);
		if (tem == NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}
		php->a = tem;
		php->capacity = newcapacity;
	}
	php->a[php->size] = x;
	//向上调整--建小堆
	if(php->size > 0)
		AdjustUp(php->a, php->size);
	php->size++;	
}

堆的删除:

删除堆是删除堆顶的数据,将堆顶的数据和最后一个数据一换,然后删除数组最后一个数据,再进行向下调整算法。

画图分析:

在这里插入图片描述

void HeapPop(HP* php)
{
	assert(php);
	assert(!HeapEmpty(php));
	Swap(&(php->a[0]), &(php->a[php->size - 1]));
	php->size--;
	AdjustDwon(php->a, php->size,0);
}

头文件(Heap.h)编写:

#pragma once

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>

typedef int HPDataType;


typedef struct Heap
{
	HPDataType* a;
	int size;
	int capacity;
}HP;
void Swap(HPDataType* p1, HPDataType* p2);
// O(logN)
void AdjustDwon(HPDataType* a, int size, int parent);
void AdjustUp(HPDataType* a, int child);

void HeapPrint(HP* php);
void HeapInit(HP* php);
void HeapDestroy(HP* php);
void HeapPush(HP* php, HPDataType x);
void HeapPop(HP* php);
HPDataType HeapTop(HP* php);
bool HeapEmpty(HP* php);
int HeapSize(HP* php);

功能文件(Heap.c)编写:

#define _CRT_SECURE_NO_WARNINGS 1

#include"Heap.h"

void Swap(HPDataType* p1, HPDataType* p2)
{
	int tem = *p1;
	*p1 = *p2;
	*p2 = tem;
}
// O(logN)
//建小堆
void AdjustDwon(HPDataType* a, int size, int parent)
{
	assert(a);
	int child = parent * 2 + 1;
	while (child < size)
	{
		//选出最小的那个
		if (child + 1 < size && a[child + 1] < a[child])
		{
			child++;
		}
		if (a[child] < a[parent] )
		{
			Swap(&(a[parent]), &(a[child]));
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}
void AdjustUp(HPDataType* a, int child)
{
	assert(a);
	while (child > 0)
	{
		int parent = (child - 1) / 2;
		if (a[child] < a[parent])
		{
			Swap(&(a[child]), &(a[parent]));
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

void HeapPrint(HP* php)
{
	assert(php);
	for (int i = 0; i < php->size; i++)
	{
		printf("%d ", php->a[i]);
	}
	printf("\n");
}
void HeapInit(HP* php)
{
	assert(php);
	php->a = NULL;
	php->capacity = php->size = 0;
}
void HeapDestroy(HP* php)
{
	assert(php);
	free(php->a);
	php->a = NULL;
	php->capacity = php->size = 0;
}
void HeapPush(HP* php, HPDataType x)
{
	assert(php);
	//扩容
	if (php->capacity == php->size)
	{
		int newcapacity = php->capacity == 0 ? 4 : php->capacity * 2;
		HPDataType* tem = (HPDataType*)realloc(php->a, sizeof(HPDataType) * newcapacity);
		if (tem == NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}
		php->a = tem;
		php->capacity = newcapacity;
	}
	php->a[php->size] = x;
	//向上调整--建小堆
	if(php->size > 0)
		AdjustUp(php->a, php->size);
	php->size++;
	
}

void HeapPop(HP* php)
{
	assert(php);
	assert(!HeapEmpty(php));
	Swap(&(php->a[0]), &(php->a[php->size - 1]));
	php->size--;
	AdjustDwon(php->a, php->size,0);
}
	
	
HPDataType HeapTop(HP* php)
{
	assert(php);
	assert(!HeapEmpty(php));
	return php->a[0];
}
bool HeapEmpty(HP* php)
{
	assert(php);
	return php->size == 0;
}
int HeapSize(HP* php)
{
	assert(php);
	return php->size;
}

测试文件(test.c)编写:

#define _CRT_SECURE_NO_WARNINGS 1

#include"Heap.h"



void HeapTest1()
{
	HP h;
	HeapInit(&h);
	HeapPush(&h, 15);
	HeapPush(&h, 18);
	HeapPush(&h, 19);
	HeapPush(&h, 25);
	HeapPush(&h, 28);
	HeapPush(&h, 34);
	HeapPush(&h, 65);
	HeapPush(&h, 49);
	HeapPush(&h, 27);
	HeapPush(&h, 37);
	HeapPush(&h, 10);
	printf("%d\n", HeapSize(&h));
	HeapPrint(&h);

	for (int i = 0; i < 8; i++)
	{
		printf("%d ", HeapTop(&h));
		HeapPop(&h);
	}
	printf("\n");
	HeapDestroy(&h);
	printf("%d ", HeapTop(&h));
	HeapPop(&h);
}

int main()
{

	HeapTest1();
	return 0;
}

运行结果测试截图:

在这里插入图片描述

总结撒花💞

   本篇文章旨在分享详解小白如何使用C语言实现堆数据结构。希望大家通过阅读此文有所收获
   😘如果我写的有什么不好之处,请在文章下方给出你宝贵的意见😊。如果觉得我写的好的话请点个赞赞和关注哦~😘😘😘

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

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

相关文章

矩阵求逆_高斯消元法

高斯消元法流程 首先必须要判断矩阵是不是一个方阵&#xff0c;其方法是对于一个矩阵AnnA_{n \times n}Ann​&#xff0c;先构造一个增广矩阵W[A∣E]W[A \mid E]W[A∣E]&#xff0c;其中EEE是一个nnn \times nnn的单位矩阵&#xff0c;这样WWW就成了一个n2nn \times 2nn2n的矩…

说说你对Event Loop(事件循环)的理解?

目录标题一、是什么二、事件循环三、宏任务和微任务微任务宏任务四、async与awaitasyncawait一、是什么 Javascript在设计之初便是单线程&#xff0c;即指程序运行时&#xff0c;只要一个线程存在&#xff0c;同一时间只能做一件事。 为了解决单线程运行阻塞问题&#xff0c;J…

【jvm系列-07】深入理解执行引擎,解释器、JIT即时编译器

JVM系列整体栏目 内容链接地址【一】初识虚拟机与java虚拟机https://blog.csdn.net/zhenghuishengq/article/details/129544460【二】jvm的类加载子系统以及jclasslib的基本使用https://blog.csdn.net/zhenghuishengq/article/details/129610963【三】运行时私有区域之虚拟机栈…

消息中间件Kafka分布式数据处理平台+ZooKeeper

目录 一.消息队列基本介绍 1.为什么需要消息队列&#xff08;MQ&#xff09; 2.使用消息队列的好处 2.1 解耦 2.2 可恢复性 2.3 缓冲 2.4 灵活性 & 峰值处理能力 2.5 异步通信 3.消息队列的两种模式 3.1 点对点模式 3.2 发布/订阅模式 二.Kafka基本介绍 1.Kaf…

【http】 get方法和Post方法区别;http和https

get方法和Post方法 get方法&#xff1a;通过url传参&#xff0c;回显输入的私密信息&#xff0c;不够私密 Post方法&#xff1a;通过正文传参&#xff0c;不会回显&#xff0c;一般私密性有保证。 一般如果上传的图片&#xff0c;音频比较大&#xff0c;推荐Post方法&#x…

Android中的AsyncTask

近期写了一个项目&#xff0c;在前台刷新界面的时候需要操作数据库&#xff0c;进行数据操作&#xff0c;在UI线程更新数据会导致ANR&#xff0c;程序十分卡&#xff0c;因此用了AsyncTask进行后台数据处理。 介绍 AsyncTask是一个用于在后台线程执行异步任务并在主线程更新U…

springboot+vue论坛管理系统(源码+文档)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的论坛管理系统。项目源码请联系风歌&#xff0c;文末附上联系信息 。 目前有各类成品java毕设&#xff0c;需要请看文末联系方式 。ja…

1.分布式电源接入对配电网影响分析

说明书 相关代码资源地址&#xff1a;风、光、负荷场景生成&#xff1b;风电出力各场景及概率&#xff1b;光伏出力各场景及概率&#xff1b;负荷各场景及概率&#xff1b;场景的削减&#xff1b;样本概率初始化&#xff1b;样本削减 基于多目标算法的冷热电联供型综合能源系…

Android 自定义View 之 圆环进度条

圆环进度条前言正文一、XML样式二、构造方法三、测量四、绘制① 绘制进度条背景② 绘制进度③ 绘制文字五、API方法六、使用七、源码前言 很多时候我们会使用进度条&#xff0c;而Android默认的进度条是长条的&#xff0c;从左至右。而在日常开发中&#xff0c;有时候UI为了让页…

亚马逊云科技为游戏全生命周期提供保障,降低游戏整体运营成本

开发一个“爆款”游戏总共需要几步&#xff1f;Marvel Snap可能会告诉你&#xff1a;第一步&#xff0c;专心致志把游戏做好、提高可玩性&#xff1b;第二步&#xff0c;把其他工作交给亚马逊云科技。 相关数据显示&#xff0c;自2022年10月18日正式发行以来&#xff0c;在不…

L2-044 大众情人分数 25分

人与人之间总有一点距离感。我们假定两个人之间的亲密程度跟他们之间的距离感成反比&#xff0c;并且距离感是单向的。例如小蓝对小红患了单相思&#xff0c;从小蓝的眼中看去&#xff0c;他和小红之间的距离为 1&#xff0c;只差一层窗户纸&#xff1b;但在小红的眼里&#xf…

【Hello Linux】信号量

作者&#xff1a;小萌新 专栏&#xff1a;Linux 作者简介&#xff1a;大二学生 希望能和大家一起进步&#xff01; 本篇博客简介&#xff1a;简单介绍linux中信号量的概念 信号量信号量的概念信号量的使用信号量函数二元信号量模拟互斥功能基于环形队列的生产者消费者模型空间资…

CSS快速入门-选择器和优先级

文章目录CSS简介选择器CSS样式优先级CSS简介 CSS是一种用于样式化网页的语言&#xff0c;全称为“层叠样式表”&#xff08;Cascading Style Sheets&#xff09;。 它可以控制网页中元素的外观和布局&#xff0c;例如颜色、字体、大小、边距、对齐等&#xff0c;让网页变得更…

消费回暖:别总想着“报复”,而该想想怎么“修复”

01 是报复性消费吗&#xff1f;「报复性消费」一词最早是在2020年武汉疫情解封之后被大家熟知。之后的三年里&#xff0c;各路机构总是预测“等到常态化防疫结束之后&#xff0c;必将迎来真正的报复性消费”&#xff0c;事实果真如此吗&#xff1f;A面&#xff1a;涨自去年年底…

健康体检管理系统源码 PEIS源码 体检小结自动生成

健康体检管理系统源码 PEIS源码 数据对接 体检小结自动生成&#xff0c;商业源码&#xff0c;有演示&#xff0c;文档齐全。自主知识产权。 文末获取联系&#xff01; 一套专业的体检管理系统源码&#xff0c;该系统涵盖个人体检、团队体检、关爱体检等多种体检类型&#xf…

Learning Tone Curves for Local Image Enhancement

作者 LUXI ZHAO , ABDELRAHMAN ABDELHAMED , AND MICHAEL S. BROWN 论文比较清晰易懂。 就是图像分8∗8648*8648∗864个patch&#xff0c; 卷积网络为RGB三个通道预测 3∗643*643∗64 个 look up table, 就是每个patch 3个1D lut. 然后每个patch的中心直接用1D lut&#xf…

spring boot对敏感信息进行加解密

我们使用jasypt最新版本对敏感信息进行加解密。 1.在项目pom文件中加入如下依赖&#xff1a; <dependency><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-spring-boot-starter</artifactId><version>3.0.3</version…

多维时序 | MATLAB实现CNN-GRU-Attention多变量时间序列预测

多维时序 | MATLAB实现CNN-GRU-Attention多变量时间序列预测 目录多维时序 | MATLAB实现CNN-GRU-Attention多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料预测效果 基本介绍 MATLAB实现CNN-GRU-Attention多变量时间序列预测&#xff0c;CNN-GRU-Attention结合注意…

Unity记录3.4-地图-柏林噪声生成 1D 地图及过渡地图

文章首发及后续更新&#xff1a;https://mwhls.top/4489.html&#xff0c;无图/无目录/格式错误/更多相关请至首发页查看。 新的更新内容请到mwhls.top查看。 欢迎提出任何疑问及批评&#xff0c;非常感谢&#xff01; 汇总&#xff1a;Unity 记录 摘要&#xff1a;柏林噪声生成…

超详细Redis入门教程——Redis概述

前言 本文小新为大家带来 超详细Redis入门教程——Redis概述 相关知识&#xff0c;具体内容包括Redis简介&#xff0c;Redis的用途&#xff0c;Redis的特性&#xff0c;Redis的IO模型&#xff08;包括&#xff1a;单线程模型&#xff0c;混合线程模型&#xff0c;多线程模型&am…