数据结构:链式二叉树

对于二叉树而言,如果不是完全二叉树,就不再适合用数组存储了

在任意二叉树中,度为0的节点都比度为2的节点多1个,即 n0 = n2 + 1

二叉树结构

typedef struct BinTreeNode
{int val;struct BinTreeNode* left;struct BinTreeNode* right;
}BTNode;

二叉树的遍历

                顺序                                访问顺序(n = NULL)

1.前序      根,左子树,右子树        1 2 3 n n n 4 5 n n 6 n n

2.中序      左子树,根,右子树        n 3 n 2 n 1 n 5 n 4 n 6 n 

3.后序      左子树,右子树,根        n n 3 n 2 n n 5 n n 6 4 1

4.层序                                         1 2 4 3 5 6 

1.前序遍历

通过递归,可以将一颗树拆解为许多棵树(直到root为空为止),是根就访问,不是,就向下走

void PreOrder(BTNode* root)
{if (root == NULL){return;}printf("%d\n", root->val);PreOrder(root->left);PreOrder(root->right);
}

2.中序遍历

同理,是左子树(该左子树不能有任何其他子树,否则就是根),就访问,不是就向下

void InOrder(BTNode* root)
{if (root == NULL){return;}PreOrder(root->left);printf("%d\n", root->val);PreOrder(root->right);
}

3.后序遍历

同理

void PostOrder(BTNode* root)
{if (root == NULL){return;}PreOrder(root->left);PreOrder(root->right);printf("%d\n", root->val);
}

4.求二叉树的大小

通过递归,将所有左子树和右子树节点遍历,再加上根本身,就是总节点数,它的本质是二叉树的后序遍历(走完根后结束)(必须将左右子树全部走完才能求出树的大小,因此一定是后序)

int TreeSize(BTNode* root)
{return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}

5.求第k层的节点个数

分割子问题 : 从第一层起的第k层的节点个数 = 第二层起的第k - 1层的节点个数

一直递归,每递归一次,k - 1,第k层时k = 1

int TreeLevel(BTNode* root, int k)
{asssert(k > 0);if (root == NULL){return 0;}if (k == 1){return 1;}//不为空且k>0说明第k层的节点再子树里return TreeLevel(root->left, k - 1) + TreeLevel(root->right, k - 1);
}

6.查找值为x的节点

注意:要保证函数存在返回值

BTNode* TreeFind(BTNode* root, int x)
{if (root == NULL){return NULL;}if (root->val == x){return root;}//在左树中找,找到返回BTNode* ret1 = TreeFind(root->left, x);if (ret1 != NULL){return ret1;}//在右树中找,找到返回BTNode* ret2 = TreeFind(root->right, x);if (ret2 != NULL){return ret2;}//树中没有x节点return NULL;
}
typedef char BTDataType;typedef struct BinaryTreeNode
{BTDataType _data;struct BinaryTreeNode* _left;struct BinaryTreeNode* _right;
}BTNode;// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* BinaryTreeCreate(BTDataType* a, int n, int* pi);//pi是下标
// 二叉树销毁
void BinaryTreeDestory(BTNode** root);
// 二叉树节点个数
int BinaryTreeSize(BTNode* root);
// 二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root);
// 二叉树第k层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k);
// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x);
// 二叉树前序遍历 
void BinaryTreePrevOrder(BTNode* root);
// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root);
// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root);
// 层序遍历
void BinaryTreeLevelOrder(BTNode* root);
// 判断二叉树是否是完全二叉树
int BinaryTreeComplete(BTNode* root);
BTNode* BinaryTreeCreate(BTDataType* a, int* pi)
{if (a[*pi] == '#')//#代表空的位置//pi是下标{(*pi)++;return NULL;}BTNode* root = (BTNode*)malloc(sizeof(BTNode));root->_data = a[*pi];root->_left = BinaryTreeCreate(a, pi);//前序递归root->_right = BinaryTreeCreate(a, pi);return root;
}void BinaryTreeDestory(BTNode** root)
{if (*root == NULL){return;}BinaryTreeDestory(&(*root)->_left);BinaryTreeDestory(&(*root)->_right);free(*root);*root = NULL;
}int BinaryTreeSize(BTNode* root)
{return root == NULL ? 0 : BinaryTreeLeafSize(root->_left) + BinaryTreeLeafSize(root->_right) + 1;
}int BinaryTreeLeafSize(BTNode* root)
{if (root == NULL)return 0;return root->_left == NULL && root->_right == NULL ?BinaryTreeLeafSize(root->_left) + BinaryTreeLeafSize(root->_right) + 1 :BinaryTreeLeafSize(root->_left) + BinaryTreeLeafSize(root->_right);
}int BinaryTreeLevelKSize(BTNode* root, int k)
{assert(k > 0);if (root == NULL)return 0;if (k == 1)return 1;return BinaryTreeLevelKSize(root->_left, k - 1) + BinaryTreeLevelKSize(root->_right, k - 1);
}BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{if (root == NULL)return NULL;if (root->_data == x)return root;//在左树BTNode* ret1 = BinaryTreeFind(root->_left, x);if (ret1 != 0)return ret1;//在右树BTNode* ret2 = BinaryTreeFind(root->_right, x);if (ret2 != 0)return ret2;//找不到return NULL;
}void BinaryTreePrevOrder(BTNode* root)
{if (root == NULL)return;printf("%d\n", root->_data);BinaryTreePrevOrder(root->_left);BinaryTreePrevOrder(root->_right);
}void BinaryTreeInOrder(BTNode* root)
{if (root == NULL)return;BinaryTreeInOrder(root->_left);printf("%d\n", root->_left);BinaryTreeInOrder(root->_right);
}void BinaryTreePostOrder(BTNode* root)
{if (root == NULL)return;BinaryTreePostOrder(root->_left);BinaryTreePostOrder(root->_right);printf("%d\n", root->_left);
}void BinaryTreeLevelOrder(BTNode* root)
{if (root == NULL)return;Queue temp;QueueInit(&temp);//先将根放入队列if(root != NULL){QueuePush(&temp, root);}//直到队列为空为止,出根,入左右子树while (QueueEmpty(&temp)){BTNode* front = QueueFront(&temp);QueuePop(&temp);printf("%d\n", front->_data);if (root->_left != NULL){QueuePush(&temp, root->_left);}if (root->_right != NULL){QueuePush(&temp, root->_right);}}QueueDestroy(&temp);
}int BinaryTreeComplete(BTNode * root){Queue qu;BTNode* cur;int tag = 0;QueueInit(&qu);QueuePush(&qu, root);while (!QueueIsEmpty(&qu)){cur = QueueTop(&qu);putchar(cur->_data);if (cur->_right && !cur->_left){return 0;}if (tag && (cur->_right || cur->_left)){return 0;}if (cur->_left){QueuePush(&qu, cur->_left);}if (cur->_right){QueuePush(&qu, cur->_right);}else{tag = 1;}QueuePop(&qu);}QueueDestroy(&qu);return 1;}

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

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

相关文章

MySQL高级学习笔记

1、MySQL架构组成 1.1 高级MySQL介绍 什么是DBA? 数据库管理员,英文是Database Administrator,简称DBA; 百度百科介绍 数据库管理员(简称DBA),是从事管理和维护数据库管理系统(D…

算法系列--递归

一.如何理解递归 递归对于初学者来说是一个非常抽象的概念,笔者在第一次学习时也是迷迷糊糊的(二叉树遍历),递归的代码看起来非常的简洁,优美,但是如何想出来递归的思路或者为什么能用递归这是初学者很难分析出来的 笔者在学习的过程中通过刷题,也总结出自己的一些经验,总结来…

【什么是Internet?网络边缘,网络核心,分组交换 vs 电路交换,接入网络和物理媒体】

文章目录 一、什么是Internet?1.从具体构成角度来看2.从服务角度来看 二、网络结构1.网络边缘1.网络边缘:采用网络设施的面向连接服务1.1.目标:在端系统之间传输数据1.2.TCP服务 2.网络边缘:采用网络设施的无连接服务2.1目标&…

探讨Java代码混淆加固工具

摘要 本篇博客将介绍几种常用的Java代码混淆工具,如ProGuard、Allatori Java Obfuscator、VirboxProtector、ipaguard和DashO。我们将深入探讨它们的特点、功能以及在保护Java应用程序安全方面的作用。此外,还将强调在使用Java代码混淆工具时需要注意的…

openssl3.2 - note - Decoders and Encoders with OpenSSL

文章目录 openssl3.2 - note - Decoders and Encoders with OpenSSL概述笔记编码器/解码器的调用链OSSL_STORE 编码器/解码器的名称和属性OSSL_FUNC_decoder_freectx_fnOSSL_FUNC_encoder_encode_fn官方文档END openssl3.2 - note - Decoders and Encoders with OpenSSL 概述 …

‍Java OCR技术全面解析:六大解决方案比较

博主猫头虎的技术世界 🌟 欢迎来到猫头虎的博客 — 探索技术的无限可能! 专栏链接: 🔗 精选专栏: 《面试题大全》 — 面试准备的宝典!《IDEA开发秘籍》 — 提升你的IDEA技能!《100天精通鸿蒙》 …

[ C++ ] STL---stack与queue

目录 stack简介 stack的常用接口 queue简介 queue的常用接口 stack的模拟实现 queue的模拟实现 stack简介 1. stack是具有后进先出操作的一种容器适配器,其只能从容器的一端进行元素的插入与删除操作; 2. stack是作为容器适配器被实现的&#xff0…

ubuntu20.04搭建rtmp视频服务

1.安装软件 sudo apt-get install ffmpeg sudo apt-get install nginx sudo apt-get install libnginx-mod-rtmp 2.nginx配置 修改/etc/nginx/nginx.conf文件,在末尾添加: rtmp {server {listen 1935;application live {live on;}} } 3.视频测试 本…

使用 ZipArchiveInputStream 读取压缩包内文件总数

读取压缩包内文件总数 简介 ZipArchiveInputStream 是 Apache Commons Compress 库中的一个类,用于读取 ZIP 格式的压缩文件。在处理 ZIP 文件时,编码格式是一个重要的问题,因为它决定了如何解释文件中的字符数据。通常情况下,Z…

权限管理系统-0.5.0

六、审批管理模块 审批管理模块包括审批类型和审批模板&#xff0c;审批类型如&#xff1a;出勤、人事、财务等&#xff0c;审批模板如&#xff1a;加班、请假等具体业务。 6.1 引入依赖 在项目中引入activiti7的相关依赖&#xff1a; <!--引入activiti的springboot启动器…

TikTok美国本土小店如何运营?常见小白问题解答

作为资深跨境老玩家&#xff0c;虽不说是经验丰富&#xff0c;至少也是摸清了基本的玩法思路。TikTok作为近来的跨境新蓝海&#xff0c;他的玩法其实并不难&#xff0c;作为第一批试错玩家&#xff0c;今天也诚心给大家分享一些美国本土小店运营经验&#xff0c;感兴趣的话就看…

当我们谈论Spring的时候到底在谈什么

题图来自APOD 你好&#xff0c;这里是codetrend专栏“Spring6全攻略”。欢迎点击关注查看往期文章。 Spring对于不做程序开发的人来说字面意思就是春天&#xff0c;四季的开始。 对于程序员来说这个单词完全拥有另外一个含义&#xff0c;Spring指的是一个开源项目&#xff0…

C语言经典算法-6

文章目录 其他经典例题跳转链接31.数字拆解32.得分排行33.选择、插入、气泡排序34.Shell 排序法 - 改良的插入排序35.Shaker 排序法 - 改良的气泡排序 其他经典例题跳转链接 C语言经典算法-1 1.汉若塔 2. 费式数列 3. 巴斯卡三角形 4. 三色棋 5. 老鼠走迷官&#xff08;一&…

Python图像处理指南:PIL与OpenCV的比较【第136篇—PIL】

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 Python图像处理指南&#xff1a;PIL与OpenCV的比较 图像处理在计算机视觉和图像识别等领域…

【极简无废话】open3d可视化torch、numpy点云

建议直接看文档&#xff0c;很多都代码老了&#xff0c;注意把代码版本调整到你使用的open3d的版本&#xff1a; https://www.open3d.org/docs/release/tutorial/visualization/visualization.html 请注意open3d应该已经不支持centos了&#xff01; 从其他格式转换成open3d…

动手做简易版俄罗斯方块

导读&#xff1a;让我们了解如何处理形状的旋转、行的消除以及游戏结束条件等控制因素。 目录 准备工作 游戏设计概述 构建游戏窗口 游戏方块设计 游戏板面设计 游戏控制与逻辑 行消除和计分 判断游戏结束 界面美化和增强体验 看看游戏效果 准备工作 在开始编码之前…

Memcached-分布式内存对象缓存系统

目录 一、NoSQL 介绍 二、Memcached 1、Memcached 介绍 1.1 Memcached 概念 1.2 Memcached 特性 1.3 Memcached 和 Redis 区别 1.4 Memcached 工作机制 1.4.1 内存分配机制 1.4.2 懒惰期 Lazy Expiration 1.4.3 LRU&#xff08;最近最少使用算法&#xff09; 1.4.4…

【07】进阶html5

HTML5 包含两个部分的更新,分别是文档和web api 文档 HTML5 元素表 元素语义化 元素语义化是指每个 HTML 元素都代表着某种含义,在开发中应该根据元素含义选择元素 元素语义化的好处: 利于 SEO(搜索引擎优化)利于无障碍访问利于浏览器的插件分析网页新增元素 多媒体…

【C++干货基地】特殊函数名的函数:赋值运算符重载

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 引入 哈喽各位铁汁们好啊&#xff0c;我是博主鸽芷咕《C干货基地》是由我的襄阳家乡零食基地有感而发&#xff0c;不知道各位的…

OceanBase生产环境安装部署的最优实践

关于生产环境&#xff0c;为了尽量确保性能和稳定性&#xff0c;我们比较建议采用标准化的配置进行部署&#xff0c;例如接下来会提到的服务初始化、日志管理和数据分盘等关键步骤。而在非生产环境中&#xff0c;如果条件满足&#xff0c;同样建议遵循规范部署的原则。 前期准备…