当前位置: 首页 > news >正文

数据结构:二叉树、堆

目录

一.树的概念

二、二叉树

1.二叉树的概念

2.特殊类型的二叉树

3.二叉树的性质

4.二叉树存储的结构

三、堆

1.堆的概念

2.堆的实现

Heap.h

Heap.c


一.树的概念

 注意,树的同一层中不能有关联,否侧就不是树了,就变成图了,例如:

由于B和C存在关联,这就不是树了。 

有关树的一些重要概念:

二、二叉树

1.二叉树的概念

二叉树由一个根节点加上两棵别称为左子树和右子树的二叉树组成

它具有两个特点:不存在度大于2的节点;子树有左右之分,次序不能颠倒,故二叉树是有序树

各类型二叉树集合:

2.特殊类型的二叉树

满二叉树:所有非叶子节点都有两个子节点,且所有叶子节点都在同一层

完全二叉树:除了最后一层,每一层都是满的,且最后一层的叶子节点都尽可能靠左排列 

二叉排序树:左子树所有节点的值小于根节点的值,右子树所有节点的值大于根节点的值,且左右子树也分别是二叉排序树

3.二叉树的性质

(1) 对于具有n个节点的完全二叉树,如果按照从上到下从左到右的顺序对所有节点从0开始编号,则序号为i的节点有:其双亲节点序号为(i-1)/2;其左孩子节点序号为i*2+1,右孩子节点序号为i*2+2,注意i*2+1和i*2+2要小于n,合法性

(2)规定根节点层数为1,具有n个节点的满二叉树深度为h=log2(n+1)

(3)规定根节点层数为1,第i层最大节点数为2^(i-1)

(4)规定根节点层数为1,深度为h的二叉树的最大节点数为2^h-1

4.二叉树存储的结构

分为顺序存储结构和链式存储结构,其中用顺序存储结构来实现完全二叉树就是接下来重点介绍的堆。

链式存储:用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。 通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址 。

顺序存储:顺序结构存储就是使用数组来存储,一般使用数组只适合表示完全二叉树,因为不是完全二叉树会有空间的浪费。而现实中使用中只有堆才会使用数组来存储。二叉树顺序存储在物理上是一个数组,在逻辑上是一颗二叉树。

、堆

1.堆的概念

堆可以看作一种特殊类型的完全二叉树,分为大堆和小堆,根节点最大的称为大堆,根节点最小的称为小堆。

大堆:谁大谁当爹,但兄弟间无绝对大小关系

小堆:谁小谁当爹,但兄第间无绝对大小关系

2.堆的实现

升序:建大堆

降序:建小堆

接下来给出建小堆的代码实现:

Heap.h

#include<stdlib.h>
#include<assert.h>
#include<stdio.h>
#include<stdbool.h>typedef int HDataType;
typedef struct Heap
{HDataType* arr;int size;int capacity;
}Heap;//堆的初始化
void HeapInit(Heap* obj);
// 堆的插入
void HeapPush(Heap* obj, HDataType x);
// 堆的删除
void HeapPop(Heap* obj);
// 取堆顶的数据
HDataType HeapTop(Heap* obj);
// 堆的数据个数
int HeapSize(Heap* obj);
// 堆的判空
bool HeapEmpty(Heap* obj);
// 堆的销毁
void HeapDestroy(Heap* obj);

Heap.c

#include"Heap.h"void HeapInit(Heap* php)
{php->capacity = php->size = 0;php->arr = NULL;
}//扩容
void Exp(Heap* obj)
{if (obj->size == obj->capacity){int new_capeccity = obj->capacity == 0 ? 4 : obj->capacity * 2;HDataType* tem = (HDataType*)realloc(obj->arr, sizeof(HDataType) * new_capeccity);if (tem == NULL){assert("realloc");}obj->arr = tem;obj->capacity = new_capeccity;}
}//交换
void Swap(HDataType* child, HDataType* parent)
{HDataType tem = *child;*child = *parent;*parent = tem;
}//向上调整
//这里假设是小堆进行调整
//如果是大堆,将if处改为大于号即可
void UpAdjust(HDataType* p,int child)
{//通过计算找父母HDataType parent = (child - 1) / 2;while (child > 0){if (p[child] < p[parent]){//交换Swap(&p[child], &p[parent]);//交换后,将parent的位置给给child,继续计算下一个parentchild = parent;//把父母给孩子parent = (child - 1) / 2;//得到新的父母}else{break;}}
}//插入
//先向堆尾插入元素,再根据大堆还是小堆向上调整
void HeapPush(Heap* obj,HDataType x)
{assert(obj);Exp(obj);obj->arr[obj->size] = x;obj->size++;//这个时候我们需要向上UpAdjust(obj->arr, obj->size - 1);
}//向下调整
//这里假设是小堆
//如果是大堆,将两个if处改为大于号即可
void DownAdjust(HDataType* p,int n,int parent)
{//计算出左孩子int child = parent * 2 + 1;while (child < n){if (child + 1 < n && p[child + 1] < p[child]) {//如果右儿子小于左儿子,直接++到右儿子的位置++child;//child+1<n是为了避免越界访问,因为每次算出的是左孩子,堆尾不一定是右孩子}if (p[child] < p[parent])//如果child<parent,就交换,要把小的往上走{//这边操作一样,算法不同Swap(&p[child], &p[parent]);parent = child;//把孩子给父母child = parent * 2 + 1;//得到新的孩子}else{break;}}
}//删除堆顶元素
//这里是小堆,删的实际是最小元素
void HeapPop(Heap* obj)
{assert(obj);assert(obj->arr);assert(obj->size > 0);//堆内无元素则不存在删的问题//1.先交换堆顶和堆尾的元素,避免中间节点之间关系全部混乱Swap(&obj->arr[0], &obj->arr[obj->size - 1]);//2.删obj->size--;//3.这里我们假设的是小堆,而当前交换后显然不是小堆,故向下调整,将堆中次小元素调到堆顶DownAdjust(obj->arr, obj->size, 0);
}//获取堆顶元素
HDataType HeapTop(Heap* obj)
{assert(obj);return obj->arr[0];
}//获取堆中数据的个数
int HeapSize(Heap* obj)
{assert(obj);return obj->size;
}//判空
bool HeapEmpty(Heap* obj)
{assert(obj);return obj->size == 0;
}//堆的销毁
void HeapDestroy(Heap* obj)
{assert(obj);assert(obj->arr);free(obj->arr);obj->arr = NULL;obj->capacity = obj->size = 0;
}

test.c

 cl:以上代码和顺序表的实现是很相似的,最大区别是堆独有的特点,也就是建堆,堆尾插入元素时进行向上调整,堆顶删除元素时进行向下调整,这两步是最关键的算法,是保证堆的特点(大小堆)的关键。

相关文章:

数据结构:二叉树、堆

目录 一.树的概念 二、二叉树 1.二叉树的概念 2.特殊类型的二叉树 3.二叉树的性质 4.二叉树存储的结构 三、堆 1.堆的概念 2.堆的实现 Heap.h Heap.c 一.树的概念 注意&#xff0c;树的同一层中不能有关联&#xff0c;否侧就不是树了&#xff0c;就变成图了&#xff…...

hi3798mv100 linux 移植

# Linux开发环境搭建 ## uboot编译 1. 必须先安装gcc&#xff0c;要不然make 等命令无法使用 2. 配置arm 交叉编译链 # gcc sudo apt-get install gcc-9 gcc -v# 安装 Linaro gcc-arm-linux-gnueabihf&#xff0c;注意不是arm-linux-gnueabihf-gcc sudo apt-get install ar…...

Docker-Harbor概述及构建

文章目录 一、Docker Harbor概述1.Harbor的特性2.Harbor的构成 二、搭建本地私有仓库三、部署 Docker-Harbor 服务四、在其他客户端上传镜像五、维护管理Harbor 一、Docker Harbor概述 Harbor 是 VMware 公司开源的企业级 Docker Registry 项目&#xff0c;其目标是帮助用户迅…...

部署项目最新教程

​ 3.3安装mysql 运行代码&#xff1a; yum install mysql 运行代码&#xff1a; yum install mysql-server 中间还是一样要输入y然后回车 运行代码&#xff1a; yum install mysql-devel 好&#xff0c;经过上面三步&#xff0c;mysql安装成功&#xff0c;现在启动mysql…...

linux证明变量扩展在路径名扩展之前执行

题目&#xff1a;怎么设计一组命令来证明变量扩展在路径名扩展之前执行。 为了证明变量扩展在路径名扩展之前执行&#xff0c;可以通过编写一个简单的 shell 脚本来观察这两个过程的顺序。我们可以使用以下步骤进行设计&#xff1a; 步骤 1&#xff1a;准备环境 在你选择的 …...

CentOS 7.9安装MySQL

下载Linux版MySQL安装包 下载地址https://downloads.mysql.com/archives/community/ 下载解压后 安装&#xff0c;按照从上至下顺序&#xff0c;一条一条执行即可安装完毕。 进入到rpm所在目录rpm -ivh mysql-community-common-8.0.26-1.el7.x86_64.rpm rpm -ivh mysql-comm…...

MacOS虚拟机安装Windows停滞在“让我们为你连接到网络”,如何解决?

1. 问题描述 MacOS在虚拟机安装win11过程中&#xff0c;停止在“让我们为你连接到网络”步骤&#xff0c;页面没有任何可以点击的按钮&#xff0c;进行下一步操作。 2. 解决方案&#xff08;亲测有效&#xff09; 到达该界面&#xff0c;按下ShiftF10&#xff08;Windows&…...

黑马程序员Java笔记整理(day03)

1.switch 2.for与while对比 3.嵌套定义,输出的区别性 4.break与continue 5.随机数生成的两种方式 6.Random 7.随机验证码...

centos7更换阿里云镜像源操作步骤及命令

centos7更换阿里云镜像源 在CentOS 7上更换为阿里云的镜像源可以通过以下步骤进行&#xff1a; 备份当前的YUM源配置文件 sudo cp -a /etc/yum.repos.d /etc/yum.repos.d.backup清理原有的YUM源配置文件 sudo rm -f /etc/yum.repos.d/*.repo下载阿里云的CentOS 7源配置文件 …...

冲刺大厂 | 一个线程调用两次start()方法会出现什么现象?

大家好&#xff0c;我是冰河~~ 今天给大家分享的面试题是&#xff1a;一个线程调用两次start()方法会出现什么现象&#xff1f;这道面试题是一道关于多线程的基础面试题&#xff0c;很多小伙伴对这个面试题不太了解&#xff0c;其实&#xff0c;如果你看过JDK中关于Thread类的…...

leaflet(一)初始化地图

Leaflet 与天地图结合使用&#xff0c;可以通过天地图提供的 API 获取地图瓦片&#xff0c;并在 Leaflet 地图上显示。 1. 安装依赖 首先&#xff0c;确保你已经安装了 Leaflet 和 Vue&#xff1a; npm install leaflet npm install vue-leaflet npm install leaflet.tilela…...

Unity开发Hololens项目

Unity打包Hololens设备 目录Visual Studio2019 / Visual Studio2022 远端部署设置Visual Studio2019 / Visual Studio2022 USB部署设置Hololens设备如何查找自身IPHololens设备门户Unity工程内的打包设置 目录 记录下自己做MR相关&#xff1a;Unity和HoloLens设备的历程。 Vi…...

立志最细,FreeRtos的中断管理(Interrupt Management)函数,详解!!!

前言&#xff1a;本文参考&#xff0c;韦东山老师开发文档&#xff0c;连接放在最后。 为什么需要中断管理函数&#xff1f; 在FreeRtos操作系统中&#xff0c;需要实时响应性&#xff0c;也就是随时随地必须保证正常多任务的运行&#xff0c;如果有中断发生&#xff0c;因为中…...

作业2-线性回归的Matlab代码实现

一、前言 相关配置&#xff1a;Matlab 2020a&#xff08;版本的影响应该不大&#xff0c;.m代码基本都能运行&#xff0c;个人感觉就是Simulink对版本的要求高一些&#xff09; 二、任务描述 基于近两节课的理论推导&#xff0c;用代码实现线性回归&#xff0c;并对预测结果进…...

用jQuery在canvas上绘制绝对定位的元素

在Web开发中,我们经常需要在canvas上精确定位和绘制元素。虽然canvas本身不支持DOM元素的定位,但我们可以借助jQuery来实现这一功能。本文将介绍如何使用jQuery在canvas上实现元素的绝对定位。 1. 基本思路 我们的基本思路是: 创建一个包含canvas的容器div将需要定位的元素放…...

Android中 tools:text 和 android:text区别

首先引入命名空间 <androidx.constraintlayout.widget.ConstraintLayoutxmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"/androidx.constraintlayout.widget.ConstraintLayout> tools:te…...

Wordpress GutenKit 插件 远程文件写入致RCE漏洞复现(CVE-2024-9234)

0x01 产品简介 GutenKit 是一个WordPress的页面构建器,在 Gutenberg 设计您的下一个 WordPress 网站。借助 Gutenberg 的原生拖放界面、50+ WordPress 块、14+ 多功能模块和 500+ 模板,您可以在几分钟内创建专业、响应迅速的 Web 内容。 0x02 漏洞概述 Wordpress GutenKit…...

Redis历史漏洞未授权RCE复现

Redis是一个开源的内存数据库&#xff0c;它用于存储数据&#xff0c;并提供高性能、可扩展性和丰富的数据结构支持。 Redis复现文章 Redisssrf漏洞利用探测内网 RedisInsight/RedisDesktopManager可视化连接工具 漏洞原理 &#xff08;1&#xff09;redis绑定在 0.0.0.0:…...

Greenhills学习总结

学习背景&#xff1a;近期参与xx项目过程中&#xff0c;遇到较多的关于代码集成编译的知识盲区&#xff0c;因此需要进行相关知识的学习和扫盲。 参考资料&#xff1a;GreenHills2017.7编译手册:本手册是GreenHills 2017.7.14版编译器的软件使用手册。该手册详细介绍了GreenHi…...

【深入学习Redis丨第八篇】详解Redis数据持久化机制

前言 Redis支持两种数据持久化方式&#xff1a;RDB方式和AOF方式。前者会根据配置的规则定时将内存中的数据持久化到硬盘上&#xff0c;后者则是在每次执行写命令之后将命令记录下来。两种持久化方式可以单独使用&#xff0c;但是通常会将两者结合使用。 一、持久化 1.1、什么…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...

网站指纹识别

网站指纹识别 网站的最基本组成&#xff1a;服务器&#xff08;操作系统&#xff09;、中间件&#xff08;web容器&#xff09;、脚本语言、数据厍 为什么要了解这些&#xff1f;举个例子&#xff1a;发现了一个文件读取漏洞&#xff0c;我们需要读/etc/passwd&#xff0c;如…...