(手撕)数据结构--->堆

文章内容

   

目录

        一:堆的相关概念与结构

        二:堆的代码实现与重要接口代码讲解


让我们一起来学习:一种特殊的数据结构吧!!!!

        一:堆的相关概念与结构

                在前面我们已经简单的学习过了二叉树的链式存储结构了,那么二叉树的顺序存储结构是啥呢?其实二叉树的顺序存储结构我们一般将他叫做

                二叉树为啥有两种形式的存储结构呢?因为堆是一种特殊的二叉树,它特殊的地方在于它的逻辑结构实际上是一颗完全二叉树,在物理结构上我们一般用数组来表示堆的结构,而如果不是完全二叉树我们一般不会用数组成为二叉树的结构,因为假如不是完全二叉树那么我们数组可能会浪费大量的空间。

        用数组作为二叉树的结构的时候我们必须要知道的双亲结点与子节点的下标关系为:

        leftchild=parent*2+1;

        rightchild=parent*2+2;

        parent=(child-1)/2;(child可以是左孩子也可以是右孩子)

        如图:完全二叉树与非完全二叉树在使用顺序存储结构的区别:

                

        在这里就能看出当结构不同时,我们需要采取不同的形式进行表示。

          总结:堆在逻辑结构上是一棵完全二叉树,在物理结构上是一个数组。对于非完全二叉树我们不适用数组的结构表示二叉树。

        


       堆的两种形式(判断数组是不是堆的方式)

        大堆:树中所有的父亲结点都大于或等于孩子结点,且根节点的值是堆中最大的数据。

        小堆:树中所有的父亲结点都小于或等于孩子结点,且根节点的值是堆中最小的数据。

        这也引出了堆的特点:1:堆中某个结点的值总是不大于或不小于父亲结点的值。

                                             2:堆总是一棵完全二叉树。

                                                        


        二:堆的代码实现与接口的讲解

        由于堆所具有的特点我们定义堆的结构为一个数组,与我们的顺序表,栈的结构类似。

        代码:


typedef int HeapDataType;typedef struct Heap
{HeapDataType* a;int Size;int Capacity;
}HP;

        接下来就是我们熟悉的接口了,一些不难理解的接口我就直接跳过,对其它类型的接口进行讲解。

        初始化堆:其实这个接口有两种初始化的代码:1:就是不开辟空间,等我们实际插入数据的时候来考虑增容和开辟空间。2:是传入一个数组然后将这个数组里面的值拷贝到我们需要开辟的空间当中。

        代码如下:

        

void InitHeap(HP* php)
{assert(php);php->a = NULL;php->Size = php->Capacity = 0;
}

       堆的销毁:直接销毁我们动态开辟的空间。

        代码如下:

void DestoryHeap(HP* php)
{assert(php);free(php->a);php->a = NULL;php->Capacity = php->Size = 0;
}

        接下来我们先讲两个重要的关于堆的算法向上调整算法与向下调整算法

        首先这两个算法的时间复杂度都是log(N)

        这两个算法在建堆的时候作用很大

        我们先讲解

        向上调整算法

                 前提:我们所插入的值前面的结构必须是堆

                接下来我们通过图的方式来讲解这个算法的工作原理

                        

        代码实现:

        

void AdjustUp(HeapDataType* a, int child)
{int parent = (child - 1) / 2;//交换的过程while (child>0){if (a[child] < a[parent]){Swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}
}

        总结算法思想:以建大堆为列,将插入的值与双亲进行比较,如果插入的值大于它的双亲的值,那么就交换孩子与双亲,可能我们插入的值非常大,那么可能会到达根节点所以我们使用循环来进行完成,最坏的情况就是我们要向上调整高度次,而完全二叉树的高度我们之前也算过,所以时间复杂度为:log(N);

        向下调整算法 

                   使用前提:左右子树都是堆

               简单图解向下调整算法:

                 

                代码如下:

                

void AdjustDown(HeapDataType* a, int n, int parent)
{int child = parent * 2 + 1;while (child < n){//找小的那个孩子if (child+1<n && a[child] >a[child + 1] ){child++;}if (a[child] < a[parent]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}

        代码是按小堆而写的        

        注意:这里我们需要考虑到一种特殊的情况,就是当我们孩子结点为最后一个结点的时候那么我们对下标为child+1的结点访问时会越界,而且我们在判断左右孩子谁小的时候我们不需要假定左孩子小这样会有几种情况且很麻烦,所以我们先假定要左孩子小,每次在判断孩子与双亲结点谁小的前面,先拿左孩子右有孩子相互比较,然后我们取小的就行。

        总结算法思想:将父亲结点与孩子结点中小的结点进行比较,然后按照时大堆还是小堆的逻辑进行相互的比较,当孩子结点为叶子结点的时候循环终止。

        插入接口:要保证插入之后我们的堆还是原来的大小堆。

        思想:我们先尾插一个值,然后将这个值进行向上调整,且每次在插入之前我们都需要进行扩容逻辑的判断。

                 代码如下:

                

void PushHeap(HP* php, HeapDataType x)
{assert(php);//先尾插到数组中去//先判断空间是否足够if (php->Capacity == php->Size){int newcapacity = php->Capacity == 0 ? 4 : php->Capacity * 2;HeapDataType* tmp = (HeapDataType*)realloc(php->a, sizeof(HeapDataType) * newcapacity);if (tmp == NULL){perror("realloc fail:");exit(-1);}php->a = tmp;php->Capacity = newcapacity;}php->a[php->Size] = x;AdjustUp(php->a, php->Size);php->Size++;
}

        总结:扩容,插入,向上调整,这几个步骤就能将这个接口给实现。

        

        堆的删除接口:这个接口需要借助向下调整算法来解决

                接口作用,能够将二叉树中最大或最小的结点值给删除,让第二大或第二小结点的值展示出来。

        算法思想:我们并不是通过移动空间来将二叉树中根节点的值给删除,因为顺序表的尾插的时间效率非常的大,所以我们一般时首先将根节点的值与最后一个值进行交换,然后再将交换后的结点进行向下调整,这样做可以得到第二大或小的值。

        代码:

        

void PopHeap(HP* php)
{assert(php);//得有元素才能删除assert(php->Size > 0);//删除的步骤//1先将根结点与尾结点交换,在删除最后一个结点Swap(&php->a[0], &php->a[(php->Size) - 1]);--(php->Size);//2在进行向下调整AdjustDown(php->a, php->a[0],0);
}

        总结:在删除之前我们还需要看我们的堆是否含有结点,然后在交换,向下调整,就可以完成这个接口了。

        这个接口与判空接口和取堆顶接口,能让我们对我们的数据打印出来是升序的或者是降序的。

        取堆顶元素的接口

                思想:直接返回数组中元素下标为0的值就行

        代码:

        

HeapDataType HeapTop(HP* php)
{assert(php);assert(php->Size > 0);return php->a[0];
}

         判断堆有多少个元素的接口

        直接return size就行

        

int HeapSize(HP* php)
{assert(php);return php->Size;
}

        堆的判空:只需要看size为不为0就行

        

bool HeapEmpty(HP* php)
{assert(php);return php->Size == 0;
}


        本章结束!!!欢迎大家的耐心观看

        

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

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

相关文章

FactoryTalk View Studio

由于项目需要&#xff0c;学习了FactoryTalk View Studio的一些操作&#xff0c;这里记录一下&#xff0c;方便以后查阅&#xff0c;并且随着项目的学习&#xff0c;随时更新。 FactoryTalk View Studio FactoryTalk View Studio 安装新建一个View Site Edition工程在工程中新建…

非常详细的git-flow分支管理流程配置及使用

非常详细的git-flow分支管理流程配置及使用。 git-flow有两个涵义,一个是指软件开发领域的版本管理流程Gitflow。另一个是指git命令工具git flow。 目前业界主流的版本管理流程是Gitflow 和 trunk-based。 Gitflow流行的比较早。但是目前的流行度要低于 trunk-based模式工作…

社区团购商城小程序v18.1开源独立版+前端

新增后台清理缓存功能 修复定位权限 修复无法删除手机端管理员 11月新登录接口修复&#xff01; 修复商家付款到零钱&#xff0c; 修复会员登陆不显示头像&#xff0c; 修复无法修改会员开添加绑定

国内AI语言大模型【文心一言】介绍

一、前言 文心一言是一个知识增强的大语言模型,基于飞桨深度学习平台和文心知识增强大模型,持续从海量数据和大规模知识中融合学习具备知识增强、检索增强和对话增强的技术特色。 最近收到百度旗下产品【文心一言】的产品,抱着试一试的心态体验了一下,整体感觉:还行! 二…

【微信小程序】网络请求

环境&#xff1a;微信小程序开发工具 测试api&#xff08;随机获取猫咪靓照&#xff09;:https://api.thecatapi.com/v1/images/search?limit2 示例&#xff1a; 完整代码 request.wxml <button bind:tap"requestBtn" type"primary">网络请求&l…

TouchGFX之缓存位图

位图缓存是专用RAM缓冲区&#xff0c;应用可将位图保存&#xff08;或缓存&#xff09;在其中。 如果缓存了位图&#xff0c;在绘制位图时&#xff0c;TouchGFX将自动使用RAM缓存作为像素来源。位图缓存在许多情况下十分有用。 从RAM读取数据通常比从闪存读取要快&#xff08;特…

重新认识架构—不只是软件设计

前言 什么是架构&#xff1f; 通常情况下&#xff0c;人们对架构的认知仅限于在软件工程中的定义&#xff1a;架构主要指软件系统的结构设计&#xff0c;比如常见的SOLID准则、DDD架构。一个良好的软件架构可以帮助团队更有效地进行软件开发&#xff0c;降低维护成本&#xff0…

OpenCV之怀旧色、冰冻滤镜、熔铸滤镜

怀旧色 源码&#xff1a; void huaijiu(Mat& src,Mat& dst) {for (int h 0;h < src.rows;h ){uchar *d1 src.ptr<uchar>(h);uchar *d2 dst.ptr<uchar>(h);for (int w 0;w < src.cols;w ){int w3 3*w;int r d1[w3 2];int g d1[w3 1];int …

微信小程序——生命周期详解(代码解读)

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

网络请求【小程序】

一、get 二、post 1.获取相应数据 Page({/*** 页面的初始数据*/data: { inptValue:, isArr:[]},/*** 生命周期函数--监听页面加载*/onLoad(options) {},onSubmit(){// console.log(this.data.inptValue)//2.后台请求数据wx.request({url: https://tea.qingnian8.com/demoArt/…

c++静态成员变量与静态成员函数

一、静态成员变量 1、说明 1.1、所有对象共享同一份静态变量 1.2、编译阶段分配内存 1.3、类内声明&#xff0c;类外初始化操作 静态成员变量&#xff0c;不属于某个具体的类对象&#xff0c;多有的类对象共享同一份数据 因此静态成员变量有两种方式访问 2、…

java微服务项目整合skywalking链路追踪框架

skywalking官网网址&#xff1a;Apache SkyWalking 目录 1、安装skywalking 2、微服务接入skywalking 3、skywalking数据持久化 1、安装skywalking 下载skywalking&#xff0c;本篇文章使用的skywalking版本是8.5.0 Index of /dist/skywalkinghttps://archive.apache.org/…

RP-母版 流程图 发布和预览 团队项目

母版 创建一个模版&#xff0c;可根据形态不同引用不同母版。若不想母版受页面变化影响&#xff0c;也可以在引用时脱离母版 创建母版&#xff1a; 1) 转换为母版 2&#xff09;在母版页面中添加 母版拖放行为 拖放行为&#xff0c;在母版名称上右键&#xff0c; 、 任意…

MySQL里的查看操作

文章目录 查看当前mysql有谁连接查看数据库或者表 查看当前mysql有谁连接 show processlist;查看数据库或者表 列出所有数据库&#xff1a; show databases;查看正在使用的数据库&#xff08;必须大写&#xff09;&#xff1a; SELECT DATABASE();列出数据库中的表&#xf…

Vulnhub实战-prime1

前言 VulnHub 是一个面向信息安全爱好者和专业人士的虚拟机&#xff08;VM&#xff09;漏洞测试平台。它提供了一系列特制的漏洞测试虚拟机镜像&#xff0c;供用户通过攻击和漏洞利用的练习来提升自己的安全技能。本次&#xff0c;我们本次测试的是prime1。 一、主机发现和端…

写一篇nginx配置指南

nginx.conf配置 找到Nginx的安装目录下的nginx.conf文件&#xff0c;该文件负责Nginx的基础功能配置。 配置文件概述 Nginx的主配置文件(conf/nginx.conf)按以下结构组织&#xff1a; 配置块功能描述全局块与Nginx运行相关的全局设置events块与网络连接有关的设置http块代理…

Android Fragment

基本概念 Fragment是Android3.0后引入的一个新的API&#xff0c;他出现的初衷是为了适应大屏幕的平板电脑&#xff0c; 普通手机开发也会加入这个Fragment&#xff0c; 可以把他看成一个小型的Activity&#xff0c;又称Activity片段&#xff01; 如果一个很大的界面&#xff…

改进YOLOv5小目标检测:构建多尺度骨干和特征增强模块,提升小目标检测

构建多尺度骨干和特征增强模块,提升小目标检测 背景代码使用配置文件如下🔥🔥🔥 提升小目标检测,创新提升 🔥🔥🔥 测试在小目标数据集进行提点 👉👉👉: 新设计的创新想法,包含详细的代码和说明,具备有效的创新组合 🐤🐤🐤 1. 本文包含两个创新改…

[.NET 6] IHostedService 的呼叫等等我的爱——等待Web应用准备就绪

📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!📢本文作者:由webmote 原创📢作者格言:新的征程,我们面对的不是技术而是人心,人心不可测,海水不可量,唯有技术,才是深沉黑夜中的一座闪烁的灯塔 !序言 在这篇文章中,我将介绍如何等…

C语言练习题解析(2)

&#x1f493;博客主页&#xff1a;江池俊的博客⏩收录专栏&#xff1a;C语言刷题专栏&#x1f449;专栏推荐&#xff1a;✅C语言初阶之路 ✅C语言进阶之路&#x1f4bb;代码仓库&#xff1a;江池俊的代码仓库&#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐ 文…