二叉树的前序遍历 、二叉树的最大深度、平衡二叉树、二叉树遍历【LeetCode刷题日志】

目录

一、二叉树的前序遍历 

方法一:全局变量记录节点个数

方法二:传址调用记录节点个数

二、二叉树的最大深度

三、平衡二叉树

四、二叉树遍历


一、二叉树的前序遍历 

 

方法一:全局变量记录节点个数

计算树的节点数:
函数TreeSize用于递归地计算二叉树中的节点数。如果树为空(即根节点为NULL),则返回0。否则,返回左子树的节点数、右子树的节点数和1(表示当前节点)的总和。

/*** Definition for a binary tree node.* struct TreeNode {*     int val;          // 节点的值  *  struct TreeNode *left;  // 指向左子节点的指针  *  struct TreeNode *right; // 指向右子节点的指针* };*/
/*** Note: The returned array must be malloced, assume caller calls free().*/
//先求树有几个节点
int TreeSize(struct TreeNode* root)
{// 如果树为空(即根节点为NULL),则返回0  // 否则,返回左子树节点数 + 右子树节点数 + 1(当前节点)return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}

_prevOrder函数:
这是一个辅助函数,用于递归地执行前序遍历。它首先将当前节点的值存储在数组a中,然后递归地遍历左子树和右子树。注意,这里直接使用了全局变量i来更新数组索引。

定义一个全局变量i

// 前序遍历二叉树的辅助函数  
void _prevOrder(struct TreeNode* root, int* a) {  // 如果当前节点为空,则直接返回  if (root == NULL) {  return;  }  // 将当前节点的值存储到数组中,并使用全局变量i作为索引  a[i] = root->val;  // 递增全局变量i  ++i;  // 递归遍历左子树  _prevOrder(root->left, a);  // 递归遍历右子树  _prevOrder(root->right, a);  
}

preorderTraversal函数:
这是主函数,用于执行前序遍历并返回结果数组。它首先使用TreeSize函数计算树的节点数,然后动态分配一个足够大的整数数组来存储结果。接下来,它调用_prevOrder函数来执行前序遍历,并填充数组。最后,它设置returnSize为树的节点数,并返回结果数组。

// 执行前序遍历并返回结果数组的主函数  
int* preorderTraversal(struct TreeNode* root, int* returnSize) {  //每次调用函数时,都要把i初始化//如果没有初始化,则i会一直叠加,无法重复使用i = 0;  // 调用TreeSize函数计算二叉树的节点数  int size = TreeSize(root);  // 动态分配结果数组,大小为节点数  int* a = (int*)malloc(size * sizeof(int));  // 调用辅助函数_prevOrder执行前序遍历,填充数组a  _prevOrder(root, a);  // 设置返回数组的大小为树的节点数,通过指针参数returnSize返回  *returnSize = size;        // 返回结果数组a的指针  return a;                  
}

方法二:传址调用记录节点个数

前面与方法一相同,不再过多赘述

_prevOrder 函数:
辅助函数,用于递归地执行前序遍历。它接受三个参数:当前节点 root、用于存储遍历结果的数组 a 和一个指向整数的指针 pi(表示当前数组索引)。函数首先将当前节点的值存储在数组 a 的相应位置,然后递增索引 pi。接下来,它递归地遍历左子树和右子树。

// 前序遍历二叉树的辅助函数  
void _prevOrder(struct TreeNode* root, int* a, int* pi) {  // 如果当前节点为空,则直接返回  if (root == NULL) {  return;  }  // 将当前节点的值存储到数组中,并递增索引pi  a[*pi] = root->val;  ++(*pi);  // 递归遍历左子树  _prevOrder(root->left, a, pi);  // 递归遍历右子树  _prevOrder(root->right, a, pi);  
}

preorderTraversal 函数:
这是主函数,用于执行前序遍历并返回结果数组。它首先调用 TreeSize 函数(虽然这里没有给出 TreeSize 的实现,但我们可以假设它的功能是计算树的节点数)来计算树的节点数,然后动态分配一个足够大的整数数组来存储结果。接着,它调用 _prevOrder 函数来执行前序遍历,并填充数组。最后,它设置 returnSize 为树的节点数,并返回结果数组。

int* preorderTraversal(struct TreeNode* root, int* returnSize) {  int i = 0; // 初始化索引为0  int size = TreeSize(root); // 假设TreeSize函数能正确计算节点数  int* a = (int*)malloc(size * sizeof(int)); // 动态分配数组  _prevOrder(root, a, &i); // 执行前序遍历,填充数组  *returnSize = size; // 设置返回数组的大小  return a; // 返回结果数组  
}

二、二叉树的最大深度

给定一个二叉树 root ,返回其最大深度。

二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     struct TreeNode *left;*     struct TreeNode *right;* };*/
int maxDepth(struct TreeNode* root) {  // 如果根节点为空,说明树是空的,因此深度为0。  if (root == NULL)  return 0;  // 递归地计算左子树的最大深度。  int leftDepth = maxDepth(root->left);  // 递归地计算右子树的最大深度。  int rightDepth = maxDepth(root->right);  // 返回左、右子树中深度较大的一个,并加上当前节点的高度1。  return leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1;  
}

三、平衡二叉树

给定一个二叉树,判断它是否是高度平衡的二叉树。

本题中,一棵高度平衡二叉树定义为:

一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     struct TreeNode *left;*     struct TreeNode *right;* };*/int maxDepth(struct TreeNode* root) {  // 如果根节点为空,说明树是空的,因此深度为0。  if (root == NULL)  return 0;  // 递归计算左子树的最大深度。  int leftDepth = maxDepth(root->left);  // 递归计算右子树的最大深度。  int rightDepth = maxDepth(root->right);  // 返回左、右子树中较大的深度值加1(加上当前节点的高度)。  return leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1;  
}
bool isBalanced(struct TreeNode* root) {  // 如果根节点为空,那么这棵空树被认为是平衡的。  if (root == NULL)  return true;  // 计算左子树的最大深度。  int leftDepth = maxDepth(root->left);  // 计算右子树的最大深度。  int rightDepth = maxDepth(root->right);  // 判断当前节点的左右子树深度差是否小于等于1,并且左右子树本身也都是平衡的。   return abs(leftDepth - rightDepth) <= 1  && isBalanced(root->left)  // 递归检查左子树是否平衡。  && isBalanced(root->right); // 递归检查右子树是否平衡。  
}

四、二叉树遍历

编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。 

#include <stdio.h>  
#include <stdlib.h> // 需要包含stdlib.h来使用malloc和exit函数  // 定义二叉树节点的结构体  
typedef struct TreeNode  
{  struct TreeNode* left;  // 左子树指针  struct TreeNode* right; // 右子树指针  char val;               // 节点值  
} TNode;  // 创建一个二叉树的函数,a是包含节点值的字符串,pi是指向当前要处理的字符的索引的指针  
TNode* CreatTree(char* a, int* pi)  
{  // 如果当前字符是'#',表示这是一个空节点  if (a[*pi] == '#')  {  ++(*pi); // 增加索引  return NULL; // 返回空指针表示这是一个空节点  }  // 为新节点分配内存  TNode* root = (TNode*)malloc(sizeof(TNode));  if (root == NULL)  {  printf("malloc fail\n"); // 如果分配失败,输出错误信息  exit(-1); // 退出程序  }  // 设置节点的值,并增加索引  root->val = a[*pi];  ++(*pi);  // 递归地创建左子树和右子树  root->left = CreatTree(a, pi);  root->right = CreatTree(a, pi);  return root; // 返回新创建的节点  
}  
// 中序遍历二叉树的函数  
void InOrder(TNode* root) // 注意:函数名应该是InOrder,而不是InOeder(这里有一个拼写错误)  
{  if (root == NULL) // 如果节点为空,直接返回  return;  InOrder(root->left);  // 遍历左子树  printf("%c ", root->val); // 输出节点的值  InOrder(root->right); // 遍历右子树  
}  int main() {  char str[100]; // 存储节点值的字符串  scanf("%s", str); // 读取输入字符串,注意应该直接传入数组名int i = 0; // 索引初始化为0  TNode* root = CreatTree(str, &i); // 创建二叉树,并将根节点赋值给root  InOrder(root); // 中序遍历二叉树并输出结果  return 0; 
}

祝大家新年快乐!!!

看到这里了还不给博主扣个:
⛳️ 点赞☀️收藏 ⭐️ 关注!

你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信呢秒回哦。

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

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

相关文章

IIS通过ARR实现负载均衡

一、实现整体方式介绍 项目中部署在windows服务器上的项目,需要部署负载均衡,本来想用nginx来配置的,奈何iis上有几个项目,把80端口和443端口占用了,nginx就用不了了(因为通过域名访问的,必须要用80和443端口),只能通过IIS的方式实现了。 这里用2个服务在一台机器上…

Flutter 混合开发 - 动态下发 libflutter.so libapp.so

背景 最近在做包体积优化&#xff0c;在完成代码混淆、压缩&#xff0c;裁剪ndk支持架构&#xff0c;以及资源压缩&#xff08;如图片转webp、mp3压缩等&#xff09;后发现安装包的中占比较大的仍是 so 动态库依赖。 具体查看发现 libflutter.so 和 libapp.so 的体积是最大的&…

nccl 源码安装与应用示例 附源码

1&#xff0c; 官方下载网址 注意&#xff0c;本文并不使用nv预编译的包来安装&#xff0c;仅供参考&#xff1a; NVIDIA Collective Communications Library (NCCL) | NVIDIA Developer 2&#xff0c;github网址 这里是nv开源的nccl源代码&#xff0c;功能完整&#xff0c;不…

侯捷C++ 2.0 新特性

关键字 nullptr and std::nullptr_t auto 一致性初始化&#xff1a;Uniform Initialization 11之前&#xff0c;初始化方法包括&#xff1a;小括号、大括号、赋值号&#xff0c;这让人困惑。基于这个原因&#xff0c;给他来个统一&#xff0c;即&#xff0c;任何初始化都能够…

C#编程-使用条件构造

使用条件构造 作判定是人的基本能力。判定也是可收编进程序。这有助于确定程序执行指令的顺序。 您可用条件构造来控制程序的流程。条件构造允许您基于被求职的表达式的结果来执行选定语句。 可以包含在C#程序中的各种条件构造是: if…else 构造switch…case 构造if…else构…

git 如何撤销历史某次merge

git&#xff0c;如何 撤销某一次历史提交或merge&#xff0c;并保留该版本的后续提交&#xff1f; 场景1&#xff1a; 你有两个功能迭代版本的分支&#xff0c;一个是 15 号上线&#xff0c;一个是25号上线。5号的时候产品突然说&#xff0c;这两个版本一起上&#xff0c;然后…

【LabVIEW FPGA入门】创建第一个LabVIEW FPGA程序

本教程仅以compactRIO&#xff08;FPGA-RT&#xff09;举例 1.系统配置 1.1软件安装 FPGA-RT 1. LabVIEW Development System (Full or Professional) 2. LabVIEW Real-Time Module 3. LabVIEW FPGA Module 4. NI-RIO drivers 1.2硬件配置 1.使用线缆连接CompactRIO至主机…

软件测试/测试开发丨Pytest结合数据驱动

安装yaml pip install pyyaml pytest结合数据驱动yaml 工程目录结构 数据准备 读取excel文件 openpyxl库的安装 openpyxl库的操作 pytest结合csv实现数据驱动 csv文件介绍 pytest结合json实现数据驱动 最后感谢每一个认真阅读我文章的人&#xff0c;礼尚往来总是要有的&…

Jmeter实现分布式并发

Jmeter实现分布式并发&#xff0c;即使用远程机执行用例。 环境&#xff1a; VMware Fusion Windows系统是win7。 操作过程 1、Master在jmeter.properties添加remote_hosts 2、Slave在jmeter.properties添加server_port 同时把remote_hosts修改为和主机&#xff08;Master…

matlab生成列是0-255渐变的图像

图像大小&#xff1a;640512 8位灰度图 %% 生成图像 %大小&#xff1a;640*512 %类型&#xff1a;灰度图 %灰度值&#xff1a;列按照0-255渐变&#xff0c;故命名为column shade。 clc,clear all,close all; %输入的图 imadouble(imread(lenna2.bmp));%原图 imargb2gray(ima)…

ubuntu系统没有网络图标的解决办法

参考文章:https://blog.csdn.net/qq_56922632/article/details/132309643 1. 执行关闭网络服务的命令&#xff0c;关闭网络服务sudo service NetworkManager stop2. 删除网络的状态文件sudo rm /var/lib/NetworkManager/NetworkManager.state3. 修改网络的配置文件sudo vi /etc…

SpringBoot—支付—支付宝

一、流程 二、沙箱操作 1.用支付宝账号登录【开放控制平台】创建应用获取 appid 2.选择沙箱模拟环境 3.沙箱应用-》获取appid(一个appid绑定一个收款支付宝账户) 4.利用开发助手工具生成RSA2密钥 公钥&#xff1a;传给支付宝平台 私钥&#xff1a;配置代码中&#xff0c;…