二叉树的链式存储

目录

  • 1.二叉树的概念和性质
  • 2.二叉树的链式存储
    • 2.1二叉树的遍历
      • 2.1.1前中后遍历
      • 2.1.2层次遍历
    • 2.2求节点的个数
    • 2.3求叶子节点的个数
    • 2.4求第k层节点个数
    • 2.5二叉树的销毁
    • 2.6怎样通过前序遍历构建二叉树
    • 2.7判断是否是满二叉树

1.二叉树的概念和性质

一,概念
1.五种形态:

  • 为空
  • 不为空
    • 根节点
    • 根节点+左子树
    • 根节点+右子树
    • 根节点+左子树+右子树

2.二叉树不存在度>2的节点
3.二叉树的子树有左右之分,次序不能颠倒,因此二叉树是有序树
在这里插入图片描述
二,性质

1.规定根节点的层数为1,则一棵非空二叉树的第k层上最多有2^(k-1)个节点
2.规定根节点的层数为1,则深度为h的二叉树的最大节点个数为2^h-1
3.对于任意一棵二叉树,n0(度为0的节点个数)=n2(度为2的节点个数)+1
4.规定根节点的层数是1,具有n个节点的满二叉树的深度,h=log(N+1).(ps:log是以2为底的对数)

2.二叉树的链式存储

typedef char BTDataType;typedef struct BinaryTreeNode
{BTDataType val;struct BinaryTreeNode* left;//左孩子struct BinaryTreeNode* right;//右孩子
}BTNode;

2.1二叉树的遍历

2.1.1前中后遍历

二叉树遍历是按照某种特定的规则,依次对二叉树的节点进行相应的操作,并且每个节点只操作一次

1.前序遍历:根节点 ,左子树, 右子树
2.中序遍历:左子树 ,根节点 ,右子树
3.后序遍历:左子树 ,右子树, 根节点

前,中,后序代码都是差不多的,唯一区别在于打印的位置不一样

前序遍历:void BinaryTreePrevOrder(BTNode* root);

//二叉树的前序遍历
void BinaryTreePrevOrder(BTNode* root)
{if (root == NULL){//printf("#");return;}printf("%c", root->val);BinaryTreePrevOrder(root->left);BinaryTreePrevOrder(root->right);
}

在这里插入图片描述

中序遍历:void BinaryTreeInOrder(BTNode* root);

// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root)
{if (root == NULL){//printf("#");return;}BinaryTreeInOrder(root->left);printf("%c", root->val);BinaryTreeInOrder(root->right);
}

后序遍历:void BinaryTreePostOrder(BTNode* root);

// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root)
{if (root == NULL){//printf("#");return;}BinaryTreePostOrder(root->left);BinaryTreePostOrder(root->right);printf("%c", root->val);
}

2.1.2层次遍历

层次遍历是自上而下,自左至右逐层访问树的节点的过程
层次遍历需要借助队列来完成
思想:将根节点入队,然后再出队,出队时,将其根节点的左节点和右节点入队。后面操作与前面一样,直到队列为空表明层次遍历完成

// 层序遍历--需要建立一个队列
void BinaryTreeLevelOrder(BTNode* root)
{Queue q;QInint(&q);//初始化if (root)QPush(&q, root);//先将根节点入队while (!QEmpty(&q)){QDataType fornt = GetFront(&q);QPop(&q);printf("%c ", fornt->val);if (fornt->left)QPush(&q, fornt->left);if (fornt->right)QPush(&q, fornt->right);}Qdestroy(&q);//销毁队列
}

在这里插入图片描述

2.2求节点的个数

思路:
1.如果二叉树为空,返回0
2.二叉树不为空

分成三部分:根节点,左子树,右子树。返回左子树+右子树+1

// 二叉树节点个数
int BinaryTreeSize(BTNode* root)
{return root == NULL ? 0 : BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}

2.3求叶子节点的个数

思路:
二叉树为空,返回0
二叉树不为空

只有一个节点,返回1.
多于一个节点,分成左子树和右子树递归
ps:叶子节点是左子树和右子树都为空的节点

// 二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root)
{if (root == NULL)return 0;if (root->left == NULL && root->right == NULL)return 1;return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
}

2.4求第k层节点个数

思路:
二叉树为空,返回0
二叉树不为空

如果k==1,返回1
k>1,左子树的k-1层+右子树的k-1层

// 二叉树第k层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k)
{if (root == NULL)return 0;if (k == 1)return 1;return BinaryTreeLevelKSize(root->left, k - 1) + BinaryTreeLevelKSize(root->right, k - 1);
}

2.5二叉树的销毁

// 二叉树销毁--后序销毁
void BinaryTreeDestory(BTNode* root)
{if (root == NULL)return;BinaryTreeDestory(root->left);BinaryTreeDestory(root->right);free(root);
}

2.6怎样通过前序遍历构建二叉树

//通过 前序 遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* BinaryTreeCreate(BTDataType* a, int* pi)//这里一定要是int*pi,或者全局变量
{if (a[*pi] == '#' || a[*pi] == '\0'){(*pi)++;return NULL;}BTNode* node = (BTNode*)malloc(sizeof(BTNode));if (node == NULL)//判断开辟空间是否成功{perror("malloc fail");exit(-1);}node->val = a[*pi];(*pi)++;node->left = BinaryTreeCreate(a,pi);node->right = BinaryTreeCreate(a,pi);return node;
}

2.7判断是否是满二叉树

需要借助队列来实现
先将根节点入队,然后出队时,将根节点的左子树和右子树入队,然后重复上述操作。当出队遇到第一个NULL时判断队列中是否还有不是空的,如果没有就表明改二叉树是满二叉树

// 判断二叉树是否是完全二叉树
bool BinaryTreeComplete(BTNode* root)
{Queue q;QInint(&q);//初始化if (root)QPush(&q, root);while (!QEmpty(&q)){QDataType fornt = GetFront(&q);QPop(&q);//遇到第一个空就可以开始判断了,如果队列不为空,就是非完全二叉树if (fornt == NULL){break;}QPush(&q, fornt->left);QPush(&q, fornt->right);}while (!QEmpty(&q)){QDataType fornt = GetFront(&q);QPop(&q);//进入下面的if中就不是完全二叉树if (fornt){Qdestroy(&q);return false;}}Qdestroy(&q);//销毁队列return true;
}

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

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

相关文章

掌握 JavaScript 基本输出方法

掌握 JavaScript 基本输出方法 前言 这是我在这个网站整理的笔记,有错误的地方请指出,关注我,接下来还会持续更新。 作者:神的孩子都在歌唱 JavaScript 是一种强大且灵活的编程语言,广泛用于 Web 开发。通过 JavaScript&#xff…

YOLOV8训练自己的数据集图文实战,包含voc数据集处理代码

yolov8官方链接: link 本文章是以labelimg标注好的voc数据集为基础,通过转换格式训练模型, 一,安装 pip install ultralyticsor pip install githttps://github.com/ultralytics/ultralytics.gitmainlink 二,数据集准备 数据集格式如下 ├── ultralytics └── datase…

RocketMq broker源码解析

broker 集群工作流程 NameSrv启动成功后,等待broker、Consumer和producer启动后也与NameSrv保持长连接, NameSrv相当于是路由控制中心。启动broker, broker与所有的NameSrv建立长连接, broker,通过定时线程定时向NameSrv发送心跳,broker信息…

LightDB pro*c迁移指南(游标模块)

文章目录 一、不使用SQLDA描述符范围的游标操作1.1 oracle 案例1.1.1 使用游标获取数据1.1.2 对于fetch结果集怎么去利用 1.2 LightDB 案例1.2.1 使用游标获取数据1.2.2 对于fetch结果集怎么去利用 3 总结:不同项 二、使用SQLDA描述符范围的游标操作2.1 Oracle样例2…

KMPlayer v2024.4.25.13 官方版 (万能播放器)

前言 KMPlaye通过各种插件扩展KMP可以支持层出不穷的新格式。KMPlaye强大的插件功能,直接从Winamp继承的插件功能,能够直接使用Winamp的音频,输入,视觉效果插件,而通过独有的扩展能力,只要你喜欢&#xff…

webman-admin多图上传预览和删除

前言 在webmen文档和论坛中都没找到多图上传的示例&#xff0c;自己找了一个&#xff0c;整合了一下凑合用 insert页面 引入css <link rel"stylesheet" href"/app/admin/admin/css/muti-upload.css" />muti-upload.css内容如下 .uploader-list .ha…

微信小程序学习

04.认识小程序项目的基本组成结构 把allow改成disallow,表示所有的页面不被微信进行索引。 比如修改首页的上面栏颜色

自制数据#国家2000投影带划分范围shp(高斯克吕格 3°/6°分带)

国家2000投影分带范围&#xff08;3&#xff09; https://www.123pan.com/s/lqEljv-xvCHA.html 国家2000投影分带范围&#xff08;6&#xff09; https://www.123pan.com/s/lqEljv-xvCHA.html 声明&#xff1a;转载此文不为商业用途。文字和图片版权归原作者所有&#xff0c;…

网络安全基础技术扫盲篇名词解释之“证书“

用通俗易懂的话说&#xff1a; 证书就好比是一张身份证&#xff08;类似&#xff0c;但不完全相同&#xff09;&#xff0c;用来证明一个网站的身份是否可信。就像你要确认一个陌生人的身份需要看他的身份证一样&#xff0c;电脑在连接一个网站时&#xff0c;也会查看网站的证…

延时性(过期/超时)和周期性的定时任务的实现方式

延时性&#xff08;过期/超时&#xff09;和周期性的定时任务的实现方式 一、延时性的定时任务&#xff08;例如订单超时30分钟后自动取消该订单&#xff09;1.使用DelayQueue实现任务即将到期提醒功能&#xff08;非分布式&#xff09;2.使用Redis实现任务即将到期提醒功能&am…

探索Web3工具:正确使用区块链平台工具的秘诀

在当今日新月异的数字时代&#xff0c;区块链技术正以惊人的速度改变着我们的生活和工作方式。尤其对于那些想要踏入区块链世界的人来说&#xff0c;正确使用区块链平台工具至关重要。本文将向您介绍一些关键的Web3工具&#xff0c;并以TestnetX.com为例&#xff0c;展示如何利…

数字化转型推动生物技术企业增长—纷享销客与集萃药康共探新动力

上周&#xff0c;在南京锦创书城&#xff0c;一场主题为“生物技术企业增长新动力&#xff1a;以客户为中心的数字化转型与创新”的研讨会圆满落幕。此次活动由纷享销客江苏分公司联合江苏集萃药康生物科技股份有限公司共同举办&#xff0c;吸引了众多生物技术领域企业的负责人…

斑消宝六周年大动作,斑小将将再迎高光时刻

如今&#xff0c;周年庆典已经成为众多品牌展示自身实力与影响力的重要舞台。这不仅仅是一个简单的庆祝活动&#xff0c;更是一次向外界展示品牌发展历程、未来规划以及团结合作伙伴的绝佳机会。在这样的背景下&#xff0c;广州斑消宝化妆品有限公司将打造别具一格的盛典&#…

npm安装依赖报错npm ERR! code ENOTFOUNDnpm ERR! syscall getaddrinfo

npm安装依赖报错 今天在学习vue的时候&#xff0c;在使用npm install vue -g来安装一个局部的vue时候&#xff0c;报出如下错误&#xff1a; npm ERR! code CERT_HAS_EXPIRED npm ERR! errno CERT_HAS_EXPIRED npm ERR! request to https://registry.npm.taobao.org/vue faile…

iphone内存满了开不了机怎么办?白苹果解决办法分享!

虽然苹果手机在使用时比较顺畅&#xff0c;但是手机用久了&#xff0c;照片、视频等资料累积过多&#xff0c;也难免会导致内存不足&#xff0c;出现无法开机卡在开机界面白苹果的情况。 内存不足导致iPhone白苹果的问题很常见&#xff0c;可以说是苹果最常见的故障之一。接下来…

【学习笔记】Windows GDI绘图(九)Graphics详解(上)

文章目录 Graphics 定义创建Graphics对象的方法通过Graphics绘制不同的形状、线条、图像和文字等通过Graphics操作对象坐标 Graphics属性Clip(裁切/绘制区域)ClipBounds获取裁切区域矩形范围CompositiongMode合成方式CompositingQuality渲染质量DpiX和DpiY 水平、垂直分辨率Int…

C++ 逻辑运算

一 逻辑运算 2 逻辑运算符 逻辑表达式 四 逻辑表达式 五 逻辑运算符的优先级 六 注意事项 注意 总结

JVM学习-字节码指令集(四)

异常处理指令 抛出异常指令 athrow指令&#xff1a;在Java程序中显示抛出异常的操作(throw语句)都是由athrow指令来实现除了throw语句显示抛出异常情况之外&#xff0c;JVM规范还规定了许多运行时异常会在其他Java虚拟机指令检测到异常状况时自动抛出&#xff0c;在之前介绍的…

vcruntime140_1.dll在哪个文件夹?详细修复vcruntime140_1.dll缺失的方法

vcruntime140_1.dll文件是什么&#xff1f;相信很多人都对它很陌生吧&#xff1f;毕竟大部分人对于dll文件还是了解得太少了&#xff0c;当突发情况出现vcruntime140_1.dll文件丢失&#xff1f;你要怎么办&#xff1f;不要担心&#xff0c;下面我们就来给大家详细的讲解一下修复…

GPT-4o:人工智能技术的新巅峰

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…