堆的数组实现

前言

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

堆的定义

什么是堆?

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

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

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

看图

那我们如何实现堆呢?

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

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

使用数组实现完全二叉树

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.mzph.cn/pingmian/12712.shtml

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

相关文章

ROS仿真多点导航

仿真环境启动&#xff1a; 1、启动并进入到相应环境&#xff1a; roscarroscar-virtual-machine:~/artcar_simulation$ 启动gazebo环境&#xff1a; roslaunch artcar_gazebo artcar_gazebo.launch 启动move_base&#xff1a; roslaunch artcar_nav artcar_move_base.launc…

3D数字化技术如何改变汽车行业?

近年来&#xff0c;新能源汽车行业加速发展&#xff0c;新车型密集发布&#xff0c;汽车保有量和车龄的增加&#xff0c;也同时点燃了汽车后市场的增长引擎。对于车企而言&#xff0c;如何全方面优化汽车从研发、生产、售后到营销的各个环节&#xff0c;以便适应快速变化的市场…

使用make_blobs生成数据并使用KNN机器学习算法进行分类和预测以及可视化

生成数据 使用make_blobs生成数据并使用matplotlib进行可视化 完整代码&#xff1a; from sklearn.datasets import make_blobs # KNN 分类器 from sklearn.neighbors import KNeighborsClassifier # 画图工具 import matplotlib.pyplot as plt # 数据集拆分工具 from sklea…

Win7远程桌面连接不上:原因及专业解决方案

Win7远程桌面连接作为一种方便的工具&#xff0c;使得用户可以从一台计算机远程访问和操作另一台计算机。然而&#xff0c;有时用户可能会遇到Win7远程桌面连接不上的情况&#xff0c;这可能是由于多种原因导致的。 一、原因分析 1. 网络设置问题&#xff1a;确保计算机与远程…

可用在vue自动导入的插件unplugin-auto-import

在大多数vue3开发中&#xff0c;基本所有页面都会引用vue3 componsition api&#xff0c;如下代码 想这种vue3 架构中自带的api&#xff0c;如果在全局配置一下的话&#xff0c;就可以减少一部分代码量&#xff0c;只是在代码编译的时候&#xff0c;会添加相应的引用&#xff…

【Stable Diffusion】 训练方法篇

一、四种模型训练方法简介 Stable Diffusion 有四种训练模型的方法&#xff1a;Textual Inversion、Hypernetwork、LoRA 和 Dreambooth 。它们的训练方法存在一定差异&#xff0c;我们可以通过下面对比来评估使用哪种训练方式最适合你的项目。 如果你知道模型中已经可以产生你…

企业架构系统之-IT系统建设如何做好技术选型

背景 近日有幸与行业同仁交流工作心得&#xff0c;在讨论中&#xff0c;他们提到一个平时工作当中我们都会遇到和经历的一个问题&#xff1a;作为架构师&#xff0c;在日常工作中应如何进行技术选型&#xff1f;面对众多框架和组件中&#xff0c;我们又应如何选择&#xff0c;…

Postgresql源码(128)深入分析JIT中的函数内联llvm_inline

相关 《Postgresql源码&#xff08;127&#xff09;投影ExecProject的表达式执行分析》 《LLVM的ThinLTO编译优化技术在Postgresql中的应用》 《LLVM&#xff08;5&#xff09;ORC实例分析》 1 JIT优化效果 create table t1(i int primary key, j int, k int); insert into t1…

Google IO 2024有哪些看点呢?

有了 24 小时前 OpenAI 用 GPT-4o 带来的炸场之后&#xff0c;今年的 Google I/O 还未开始&#xff0c;似乎就被架在了一个相当尴尬的地位&#xff0c;即使每个人都知道 Google 将发布足够多的新 AI 内容&#xff0c;但有了 GPT-4o 的珠玉在前&#xff0c;即使是 Google 也不得…

秋招算法——AcWing101——拦截导弹

文章目录 题目描述思路分析实现源码分析总结 题目描述 思路分析 目前是有一个笨办法&#xff0c;就是创建链表记录每一个最长下降子序列所对应的节点的链接&#xff0c;然后逐个记录所有结点的访问情况&#xff0c;直接所有节点都被访问过。这个方法不是很好&#xff0c;因为需…

消防物资存储|基于SSM+vue的消防物资存储系统的设计与实现(源码+数据库+文档)

消防物资存储系统 目录 基于SSM&#xff0b;vue的消防物资存储系统的设计与实现 一、前言 二、系统设计 三、系统功能设计 1用户功能模块 2 管理员功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介…

动规解决01背包/完全背包精讲

还不会用动态规划解决01背包/完全背包&#xff1f;看这一篇文章就够了&#xff01; 首先我们要明白什么是01背包和完全背包。 背包问题总体问法就是&#xff1a; 你有一个背包&#xff0c;最多能容纳的体积是V。 现在有n个物品&#xff0c;第i个物品的体积为vi​ ,价值为wi​…

干货教程【AI篇】| Topaz Video Enhance AI超好用的视频变清晰变流畅的AI工具,免费本地使用

关注文章底部公众号&#xff0c;回复关键词【tvea】即可获取Topaz Video Enhance AI。 一款非常好用的视频变清晰变流畅的AI工具&#xff0c;即提高视频的分辨率和FPS&#xff0c;亲测效果非常nice&#xff01;&#xff01; 免费&#xff01;免费&#xff01;免费&#xff01…

【案例】使用Vue实现标题项元素上下移动

效果图 效果说明 每一组数据只能在对应的二级类目中进行上下移动&#xff0c;当点击上移图标的时候【左边的】会将当前元素与上一个元素交换位置&#xff0c;当点击的元素为该组的第一个元素时&#xff0c;将提示已经是第一项了并且不能进行移动&#xff1b;当点击下移图标的时…

Linux|如何允许 awk 使用 Shell 变量

引言 当我们编写 shell 脚本时&#xff0c;我们通常会在脚本中包含其他较小的程序或命令&#xff0c;例如 awk 操作。就 Awk 而言&#xff0c;我们必须找到将一些值从 shell 传递到 Awk 操作的方法。 这可以通过在 Awk 命令中使用 shell 变量来完成&#xff0c;在本文中&#x…

C++系统编程篇——Linux初识(系统安装、权限管理,权限设置)

(1)linux系统的安装 双系统---不推荐虚拟机centos镜像&#xff08;可以使用&#xff09;云服务器/轻量级云服务器&#xff08;强烈推荐&#xff09; ①云服务器&#xff08;用xshell连接&#xff09; ssh root公网IP 然后输入password ①添加用户&#xff1a; addus…

揭秘!你的电商产品为何滞销?同行火爆销售的7大原因!

同样做电商&#xff0c;但自家产品销量不如竞对同行&#xff0c;可能的原因有多种&#xff0c;以下是店雷达总结7个可能的原因和对策&#xff1a; 一、市场竞争分析不足 未能准确识别并分析竞争对手的产品、定价、营销策略等关键信息&#xff0c;导致自身产品无法脱颖而出。 …

机器学习(四) ----------逻辑回归

目录 1 概述 2 极大似然估计 3 逻辑回归核心思想 3.1 对数似然损失&#xff08;Log-likelihood Loss&#xff09; 4 分类问题的评估方法 4.1 混淆矩阵&#xff08;Confusion Matrix&#xff09;&#xff1a; 4.2 准确率&#xff08;Accuracy&#xff09; 4.3 精确率&am…

数据结构与算法学习笔记三---栈和队列

目录 前言 一、栈 1.栈的表示和实现 1.栈的顺序存储表示和实现 1.C语言实现 2.C实现 2.栈的链式存储表示和实现 1.C语言实现 2.C实现 2.栈的应用 1.数制转换 二、队列 1.栈队列的表示和实现 1.顺序队列的表示和实现 2.链队列的表示和实现 2.循环队列 前言 这篇文…

P9748 [CSP-J 2023] 小苹果:做题笔记

目录 P9748 [CSP-J 2023] 小苹果 思路 代码 P9748 [CSP-J 2023] 小苹果 P9748 [CSP-J 2023] 小苹果 思路 先写几个看看规律 题意我们能看出来是三个三个一组的&#xff0c;然后每次取走的都是三个里面的第一个。我们应该很容易想到如果一轮的总数是三的倍数的话&#xff0…