堆的数组实现

前言

本次博客来讲解一下堆的数组实现,好吧还是会结合图例,让大家理解

堆的定义

什么是堆?

堆是一颗完全二叉树。它的性质是父节点一定大于或者一定小于子节点

每一个结点都要满足这个性质就是堆

堆的特性是堆顶的数据一定是最大或最小,最大为大堆,最小为小堆

看图

那我们如何实现堆呢?

我们可以注意堆是一个完全二叉树,我们可以使用一个数组来模拟完全二叉树

那么如何使用数组实现完全二叉树

使用数组实现完全二叉树

OK,首先我们可以通过数组下标,来确定节点,只要能够得到父子关系就可以遍历整个完全二叉树,看图吧

OK,那么咱么可不可以实现一下前序遍历呢

使用递归和非递归

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#define N 10
//适用于满二叉树和完全二叉树
typedef struct BianryTree {int a[N];
}BT;
void InitBinaryTree(BT* bt,int cursize)
{if (cursize >= N)return;bt->a[cursize] = cursize;InitBinaryTree(bt,cursize*2+1);InitBinaryTree(bt,cursize*2+2);
}
void TraversalTree(BT* bt, int cursize)
{if (cursize >= N)return;printf("%d ", bt->a[cursize]);TraversalTree(bt, cursize * 2 + 1);TraversalTree(bt, cursize * 2 + 2);
}
int main()
{BT* bt = (BT*)malloc(sizeof(BT));InitBinaryTree(bt,0);TraversalTree(bt, 0);return 0;
}

上面是前序遍历属于递归遍历

接下来看非递归遍历,其实可以

void TraversalTree(BT* bt, int cursize)
{while (cursize < N)printf("%d ", bt[cursize++]);
}

只需改一改就好,这里相当于层序遍历

那么使用数组去实现完全二叉树是可行的

数组实现堆

我们先看看堆有哪些接口,然后一一实现

看一看头文件吧

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
typedef int HpDatatype;
typedef struct Heap {HpDatatype* a;int capacity;int size;
}HP;
void IintHeap(HP* hp);
void PushHeap(HP* hp, HpDatatype x);
void PopHeap(HP* hp);
HpDatatype TopHeap(HP* hp);
void DestroyHeap(HP* hp);
bool EmptyHeap(HP* hp);
int SizeHeap(HP* hp);

 OK

先实现几个简单的   初始化,没什么好说的

void IintHeap(HP* hp)
{hp->a = NULL;hp->capacity = 0;hp->size = 0;
}

  返回堆大小,也没有什么好说的

int SizeHeap(HP* hp)
{assert(hp);return hp->size;
}

返回堆顶

HpDatatype TopHeap(HP* hp)
{assert(hp);assert(hp->size > 0);return hp->a[0];
}

判空

bool EmptyHeap(HP* hp)
{assert(hp);return hp->size == 0;
}

销毁堆

void DestroyHeap(HP* hp)
{assert(hp);free(hp->a);hp->capacity = 0;hp->size = 0;
}

插入数据

void PushHeap(HP* hp, HpDatatype x)
{assert(hp);//检查容量if (hp->size == hp->capacity){int newcapacity = hp->capacity == 0 ? 4 : hp->capacity * 2;HpDatatype* temp = (HpDatatype*)realloc(hp->a, sizeof(HpDatatype) * newcapacity);if (temp == NULL){printf("realloc fail\n");return;}else{hp->a=temp;hp->capacity = newcapacity;}}//向上调整法hp->a[hp->size++] = x;AdjustUp(hp->a,hp->size-1);
}

这个代码的逻辑是,每插入一个数据,对该数据进行向上调整法

那么向上调整法可以确保,每插入一个数据,该数组保持为堆

那么现在我们画图来理解什么是向上调整法

OK,下面是向上调整法

void AdjustUp(HpDatatype* a, int child)
{//这里的向上调整法是调整它的祖先while (child > 0){int parent = (child - 1) / 2;if (a[child] < a[parent]){int temp = a[child];a[child] = a[parent];a[parent] = temp;child = parent;}else{break;}}
}


删除一个数据

void PopHeap(HP* hp)
{assert(hp);assert(hp->a > 0);swap(&hp->a[0], &hp->a[hp->size - 1]);//向下调整法AdjustDown(hp->a, 0, hp->size);hp->size--;
}

 我们要删除的是堆顶的数据

所以让第一个数据与最后一个数据交换,size--

此时,第一个节点的左子树和右子树都是堆,我们只要再调整一下根节点即可

这种调整叫做向下调整法

这里就不画图了,有点麻烦

直接看代码吧

void AdjustDown(HpDatatype* a, int start, int end)
{int parent = start;//假设法,假设左孩子更接近目的int child = parent * 2 + 1;end = end - 1;while (child <end){if (child + 1 < end && a[child + 1] < a[child])child++;if (a[parent] > a[child]){swap(&a[child],&a[parent]);parent = child;child = parent * 2 + 1;}elsebreak;}
}

 这里的逻辑就是,先使用假设法让child唯一

然后,比对a[child]和a[parent]的大小 满足条件则交换

大堆 a[child]>a[parent]    小堆 a[child]<a[parent]

如果不满足条件,直接结束.

测试堆

看图吧

 这是小堆,所以是升序,也算是完成了

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

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

相关文章

PyCharm2023 社区版安装 +中文语言包+配置教程+Python环境搭建

一、Python 安装 我们在安装Pycharm之前&#xff0c;首先要先安装Python环境也就是安装Python解释器 因为PyCharm是一个用于编写和调试Python代码的开发工具&#xff0c;而Python解释器是用于解释执行Python代码PyCharm需要依赖Python解释器来执行Python代码&#xff0c;因此…

Jmeter接口测试和Jmeter接口自动化测试

一、Jmeter 的使用步骤 打开Jmeter 安装包&#xff0c;进入\bin 中&#xff0c;找到"jmeter.bat", 点击打开即可。 在下图打开的Jmeter 页面中&#xff0c;右键“测试计划” -> “添加” -> "Threads(Users)" -> “线程组”&#xff0c; 建立线程…

[图解]SysML和EA建模住宅安全系统-04

1 00:00:01,200 --> 00:00:04,710 我们首先来看一下需求图的一些要点 2 00:00:05,810 --> 00:00:07,080 需求图用来干什么 3 00:00:07,210 --> 00:00:12,080 用来记录文本形式的一些需求 4 00:00:12,090 --> 00:00:13,480 和需求的素材 5 00:00:14,540 --> …

xilinx fpga bit流文件转成bin/mcs/hex文件的tcl语句操作

xilinx fpga bit流文件中包含工程的相关信息以及主体程序的二进制文件&#xff0c;bit文件只能在线加载&#xff0c;掉电丢失。因此需要转成bin/mcs文件&#xff0c;固化到flash中。 此处以转成bin文件为例 vivado2018软件中似乎没有单独将已经生成的bit转成bin文件的小工具&…

仓库管理流程详解(附作业流程图)

仓库管理流程在企业的日常运营中至关重要。它不仅是物资流转的核心环节&#xff0c;更关乎着企业的运营效率、成本控制和客户服务水平。一个高效、规范的仓库管理流程能够确保货物从入库到出库的各个环节有序进行&#xff0c;减少资源浪费和时间成本&#xff0c;同时帮助企业实…

【案例教程】土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测

查看原文>>>土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测 土地利用/土地覆盖数据是生态、环境和气象等领域众多模型的重要输入参数之一。基于遥感影像解译&#xff0c;可获取历史或当前任何一个区域的土地利用/土地覆盖数据&#xff0c;用于评估区域的生…

服务器被后台爆破怎么处理

服务器后台遭受密码爆破攻击是网络安全中常见的威胁之一&#xff0c;这种攻击通过不断尝试不同的用户名和密码组合来破解系统登录凭证&#xff0c;一旦成功&#xff0c;攻击者便能非法访问系统资源。 本文将介绍如何识别此类攻击&#xff0c;并采取有效措施进行防御&#xff0c…

1:硬件测试面试

1&#xff1a;板级测试 . JTAG和Boundary Scan 对于硬件板级测试&#xff0c;我使⽤JTAG和Boundary Scan技术进⾏⾃动化测试。这些技术可以帮助我访问PCB 上的芯⽚引脚&#xff0c;从⽽进⾏信号测量、连通性测试和故障诊断。 2&#xff1a;整机测试 3&#xff1a;测试准备 4…

AI 一键生成高清短视频,视频 UP 主们卷起来...

现在短视频越来越火&#xff0c;据统计&#xff0c;2023年全球短视频用户数量已达 10 亿&#xff0c;预计到2027年将突破 24 亿。对于产品展示和用户营销来说&#xff0c;短视频已经成为重要阵地&#xff0c;不管你喜不喜欢它&#xff0c;你都得面对它&#xff0c;学会使用它。…

记录计全支付切换到RabbitMQ时启动报错的问题

记录计全支付切换到RabbitMQ时启动报错的问题 首先在application.yml中切换到RabbitMQ配置安装RabbitMQ、Erlang、延时插件 rabbitmq_delayed_message_exchange&#xff0c;延迟插件必装 首先在application.yml中切换到RabbitMQ配置 # 第一处rabbitmq:addresses: 127.0.0.1:56…

2024/5/15 英语每日一段

Many pet owners are now turning to pet insurance policies to avoid higher vet bills should something bad happen unexpectedly. But Carlson said that preventive veterinary care—like vaccination, parasite control and weight management—is "the best way …

做私域,该如何从公域向私域引流?

说到私域运营&#xff0c;很多人首先就会想到&#xff1a;私域流量。企业做私域&#xff0c;流量从哪来&#xff1f;该怎样去引流&#xff1f;又该如何保障私域流量的质量等一系列问题&#xff0c;都需要企业一一解决。所以&#xff0c;今天&#xff0c;我们就来探讨一下&#…