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

【二叉树遍历算法应用】------补录

0.二叉树结点的链式存储结构

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>typedef char TElemType;//树中元素基本类型为char类型//二叉树结点链式存储结构(二叉链表)
typedef struct BiNode
{TElemType data;//数据域struct BiNode* lchild, * rchild;//左,右孩子指针
}BiNode,*BiTree;
//BiNode:用来定义结点类型
//BiTree:用来定义树类型

1.复制二叉树

int CopyBiTree(BiTree b,BiTree* newb)

注意:原本存在的树只是会遍历,不会被修改,故传入一级指针
但要复制成的新树,应传入结点指针的地址,即二级指针,因为要修改结点指针的值(指向新开辟的结点空间)

1.1算法步骤:

(1)返回条件:当前根结点为空,注意复制完空结点之后再返回
(2)当前结点非空,申请新结点空间并复制根结点
(3)递归复制左子树(注意传入New树待修改指针的地址)
(4)递归复制右子树(注意传入New树待修改指针的地址)

//1.先序复制二叉树      (万变不离其宗,就是先序遍历算法的变种)
//注意:原本存在的树只是会遍历,不会被修改,故传入一级指针
//但要复制成的新树,应传入结点指针的地址,即二级指针,因为要修改结点指针的值(指向新开辟的结点空间)
int CopyBiTree(BiTree b,BiTree* newb)
{//[1]返回条件:当前根结点为空,注意复制完空结点之后再返回if (b == NULL){(*newb) = NULL;//易错1:忘记复制空结点return 0;}//[2]当前结点非空,申请新结点空间,复制根结点(*newb) = (BiNode*)malloc(sizeof(BiNode));if (!(*newb)){printf("内存分配失败!\n");exit(-1);}(*newb)->data = b->data;//[3]递归复制左子树CopyBiTree(b->lchild, &((*newb)->lchild));//注意传入New树待修改指针的地址//[4]递归复制右子树CopyBiTree(b->rchild, &((*newb)->rchild));
}

2.计算二叉树的深度

  • 深度回顾:指从头结点开始到最远的叶子结点,路径上的结点数【注意:包括头结点】
int DepthBiTree(BiTree b)

注意:只进行遍历,不会修改树的结构,故传入一级指针

2.1算法步骤:

(1)返回条件:当前根结点为空,返回0
(2)递归计算左子树的深度记为m
(3)递归计算右子树的深度记为n
(4)返回子树的深度:即m和n中的较大值,并加1
加1是因为子树根结点要算上;
返回较大值是因为深度 应该是最远路径上的结点总数,

//2.计算二叉树深度  (树的深度:指从头结点开始到最远的叶子结点,路径上的结点数【注意:包括头结点】)
//注意:只进行遍历,不会修改树的结构,故传入一级指针
int DepthBiTree(BiTree b)
{//[1]返回条件:当前根结点为空,返回0if (b == NULL){return 0;}//[2]递归计算左子树的深度记为mint m = DepthBiTree(b->lchild);//[3]递归计算右子树的深度记为nint n = DepthBiTree(b->rchild);//[4]返回子树的深度:即m和n中的较大值,并加1//加1是因为子树根结点要算上return (m > n) ? m + 1 : n + 1;
}

3.计算二叉树中结点总数

int NodeCount(BiTree b)

3.1算法步骤:

(1)返回条件:当前根结点为空,返回0
(2)递归计算左子树的结点总数记为m
(3)递归计算右子树的结点总数记为n
(4)返回子树的结点总数:即m和n之和,并加1
加1是因为子树根结点要算上

//3.计算二叉树中结点总数
int NodeCount(BiTree b)
{//[1]返回条件:当前根结点为空,返回0if (b == NULL){return 0;}//[2]递归计算左子树的结点总数记为mint m = NodeCount(b->lchild);//[3]递归计算右子树的结点总数记为nint n = NodeCount(b->rchild);//[4]返回子树的结点总数:即m和n之和,并加1//加1是因为子树根结点要算上return m + n + 1;
}

4.计算二叉树中叶子结点总数

  • 回顾叶子结点:左子树和右子树均为空的结点,一般在完全二叉树的最下面
int LeadCountBiTree(BiTree b)

4.1算法步骤

(1)返回条件1:当前根结点为空,返回0
(2)返回条件2:当前结点为叶子结点,返回1
两个返回条件缺一不可
(3)递归计算左子树和右子树的叶子结点总数记为m和n
(4)返回子树的叶子结点总数:即m和n之和

//4.计算二叉树中叶子结点总数(叶子结点:左子树和右子树均为空的结点,一般在完全二叉树的最下面)
int LeadCountBiTree(BiTree b)
{//[1]返回条件1:当前根结点为空,返回0if (b == NULL){return 0;}//[2]返回条件2:当前结点为叶子结点,返回1if (b->rchild == NULL && b->lchild == NULL){return 1;}//[3]递归计算左子树和右子树的叶子结点总数记为m和nint m = LeadCountBiTree(b->lchild);int n = LeadCountBiTree(b->rchild);//[4]返回子树的叶子结点总数:即m和n之和return m+n;
}

5.整体代码实现

  • 样例树:应输入序列
    abc##de###fg#h###
  • 复制后新树的先序序列为:
    abcdefgh
  • 深度:4
  • 结点总数:8
  • 叶子结点总数:3
    在这里插入图片描述
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>typedef char TElemType;typedef struct BiNode
{TElemType data;struct BiNode* lchild, * rchild;
}BiNode,*BiTree;//.先序遍历
bool PreOrderTraverse(BiTree b)
{if (b == NULL){return true;}printf("%c", b->data);//根PreOrderTraverse(b->lchild); //左PreOrderTraverse(b->rchild); //右}//先序建立整树
bool CreateBiTree(BiTree * b)
{//[0]TElemType ch;scanf_s("%c", &ch);if (ch == '#'){(*b) = NULL;}else{(*b) = (BiNode*)malloc(sizeof(BiNode));if (!(*b)){printf("内存分配失败!\n");exit(-1);}(*b)->data = ch;//根CreateBiTree(&((*b)->lchild)); //左CreateBiTree(&((*b)->rchild));//右}return true;
}//1.先序复制二叉树      (万变不离其宗,就是先序遍历算法的变种)
//注意:原本存在的树只是会遍历,不会被修改,故传入一级指针
//但要复制成的新树,应传入结点指针的地址,即二级指针,因为要修改结点指针的值(指向新开辟的结点空间)
int CopyBiTree(BiTree b,BiTree* newb)
{//[1]返回条件:当前根结点为空,注意复制完空结点之后再返回if (b == NULL){(*newb) = NULL;//易错1:忘记复制空结点return 0;}//[2]当前结点非空,申请新结点空间,复制根结点(*newb) = (BiNode*)malloc(sizeof(BiNode));if (!(*newb)){printf("内存分配失败!\n");exit(-1);}(*newb)->data = b->data;//[3]递归复制左子树CopyBiTree(b->lchild, &((*newb)->lchild));//注意传入New树待修改指针的地址//[4]递归复制右子树CopyBiTree(b->rchild, &((*newb)->rchild));
}//2.计算二叉树深度  (树的深度:指从头结点开始到最远的叶子结点,路径上的结点数【注意:包括头结点】)
//注意:只进行遍历,不会修改树的结构,故传入一级指针
int DepthBiTree(BiTree b)
{//[1]返回条件:当前根结点为空,返回0if (b == NULL){return 0;}//[2]递归计算左子树的深度记为mint m = DepthBiTree(b->lchild);//[3]递归计算右子树的深度记为nint n = DepthBiTree(b->rchild);//[4]返回子树的深度:即m和n中的较大值,并加1//加1是因为子树根结点要算上return (m > n) ? m + 1 : n + 1;
}//3.计算二叉树中结点总数
int NodeCount(BiTree b)
{//[1]返回条件:当前根结点为空,返回0if (b == NULL){return 0;}//[2]递归计算左子树的结点总数记为mint m = NodeCount(b->lchild);//[3]递归计算右子树的结点总数记为nint n = NodeCount(b->rchild);//[4]返回子树的结点总数:即m和n之和,并加1//加1是因为子树根结点要算上return m + n + 1;
}//4.计算二叉树中叶子结点总数(叶子结点:左子树和右子树均为空的结点,一般在完全二叉树的最下面)
int LeadCountBiTree(BiTree b)
{//[1]返回条件1:当前根结点为空,返回0if (b == NULL){return 0;}//[2]返回条件2:当前结点为叶子结点,返回1if (b->rchild == NULL && b->lchild == NULL){return 1;}//[3]递归计算左子树和右子树的叶子结点总数记为m和nint m = LeadCountBiTree(b->lchild);int n = LeadCountBiTree(b->rchild);//[4]返回子树的叶子结点总数:即m和n之和return m+n;
}int main()
{BiTree T;CreateBiTree(&T);PreOrderTraverse(T);printf("\n");BiTree NewT;CopyBiTree(T,&NewT);PreOrderTraverse(NewT);printf("NewT的深度为:%d\n", DepthBiTree(NewT));printf("NewT的结点总数为:%d\n", NodeCount(NewT));printf("NewT的叶子结点总数为:%d\n", LeadCountBiTree(NewT));return 0;
}

在这里插入图片描述

相关文章:

【二叉树遍历算法应用】------补录

0.二叉树结点的链式存储结构 #include<stdio.h> #include<stdlib.h> #include<stdbool.h>typedef char TElemType;//树中元素基本类型为char类型//二叉树结点链式存储结构&#xff08;二叉链表&#xff09; typedef struct BiNode {TElemType data;//数据域…...

AtCoder Beginner Contest 368

A.Cut&#xff08;模拟&#xff09; 题意&#xff1a; 有一叠 N N N张扑克牌&#xff0c;最上面的 i i i张扑克牌上写着一个整数 A _ i A\_i A_i。 你从牌堆底部取出 K K K张牌&#xff0c;将它们放在牌堆顶部&#xff0c;并保持它们的顺序。 操作后从上到下输出写在卡…...

WebGL系列教程六(纹理映射与立方体贴图)

目录 1 前言2 思考题3 纹理映射介绍4 怎么映射&#xff1f;5 开始绘制5.1 声明顶点着色器和片元着色器5.2 修改顶点的颜色为纹理坐标5.3 指定顶点位置和纹理坐标的值5.4 获取图片成功后进行绘制5.5 效果5.6 完整代码 6 总结 1 前言 上一讲我们讲了如何使用索引绘制彩色立方体&a…...

为什么nii.gz转.nrrd标签体积变大?

import SimpleITK as sitk # nii nii.gz nrrd格式之间互相转换 def nii2nii(oripath, savepath):data sitk.ReadImage(oripath)img sitk.GetArrayFromImage(data)out sitk.GetImageFromArray(img)sitk.WriteImage(out, savepath)if __name__ __main__:oripath 00292625.ni…...

软件安装攻略:EmEditor编辑器下载安装与使用

EmEditor是一款在Windows平台上运行的文字编辑程序。EmEditor以运作轻巧、敏捷而又功能强大、丰富著称&#xff0c;得到许多用户的好评。Windows内建的记事本程式由于功能太过单薄&#xff0c;所以有不少用户直接以EmEditor取代&#xff0c;emeditor是一个跨平台的文本编辑器&a…...

Redis的watch机制详解

WATCH 是 Redis 提供的一个用于实现 乐观锁 (Optimistic Lock) 的命令&#xff0c;通常用于实现事务中的并发控制。它允许客户端监控一个或多个键的变化&#xff0c;并确保事务&#xff08;MULTI/EXEC&#xff09;中执行的操作在这些键没有发生改变的情况下才能成功提交。若在事…...

UnrealEngine 打包Android平台应用

虚幻引擎 支持将项目发布到 安卓&#xff08;Android&#xff09; 移动设备上&#xff0c;并且提供了若干功能帮你将项目发布到 谷歌游戏商店。本节包含了如何设置Android开发环境、如何使用Android功能和服务、以及如何为发布游戏做准备相关的指南。 当前SDK要求 当前UE版本…...

Linux:git

hello&#xff0c;各位小伙伴&#xff0c;本篇文章跟大家一起学习《Linux&#xff1a;git》&#xff0c;感谢大家对我上一篇的支持&#xff0c;如有什么问题&#xff0c;还请多多指教 &#xff01; 如果本篇文章对你有帮助&#xff0c;还请各位点点赞&#xff01;&#xff01;&…...

electron有关mac构建

针对 Mac M1/2/3 芯片的设备&#xff0c;proces.archarm64. 执行下面命令&#xff0c;检查下按照的 node.js 版本是不是 intel x64 指令集&#xff0c;如果是的话安装下 arm64 指令集的 node.js终端中执行以下命令&#xff1a;node -p process.arch 对应的node版本也是arm版 …...

C语言-数据结构 弗洛伊德算法(Floyd)邻接矩阵存储

弗洛伊德算法相比迪杰斯特拉相似的地方都是遍历邻接矩阵不断调整最短路径的信息&#xff0c;并且两种算法面对多源最短路径的时间复杂度都是O(n^3)&#xff0c;Floyd采用的是动态规划而Dijkstra是采用贪心的思想。在Floyd中我们将创建两个数组进行辅助&#xff0c;一个path二维…...

pyspark 安装记录

1、安装软件 1、python 3.10 2、hadoop-3.3.4 里面的winutils 要记得添加 3、java-17 4、spark-3.5.1-bin-hadoop3 python 安装 pyspark,Jupyter notebook pip install pyspark pip install jupyter notebook 2、添加环境变量 JAVA_HOME=C:\PySparkService\java-17H…...

高度可定制的电竞鼠标,雷柏VT1 PRO MAX体验

不管是菜鸟还是老鸟&#xff0c;游戏玩到某个阶段很容易出现瓶颈&#xff0c;在游戏的某个阶段&#xff0c;这里面制约最大的除了操作之外&#xff0c;实际上还是我们用的硬件。比如在PC游戏中&#xff0c;鼠标的影响就非常大&#xff0c;像是在游戏中如果鼠标延迟过高&#xf…...

经验笔记:SOA(面向服务的架构)

SOA&#xff08;面向服务的架构&#xff09;经验笔记 引言 SOA&#xff08;Service-Oriented Architecture, 面向服务的架构&#xff09;是一种设计原则&#xff0c;用于构建灵活且可扩展的分布式系统。SOA强调将应用程序的不同功能封装为独立的服务&#xff0c;这些服务通过…...

triton之ttir学习

一 基本语句 1 常量 %cst arith.constant dense<520192> : tensor<4096xi32> %c127_i32 arith.constant 127 : i32 %cst arith.constant dense<520192> : tensor<4096xi32> 解释&#xff1a;这条语句定义了一个名为 %cst 的常量&#xff0c;它…...

如何在AWS账户上进行充值:一份详尽指南

大家好&#xff0c;小编今天给大家带来一份关于如何在AWS账户上进行充值的详尽指南。对于使用AWS服务的用户来说&#xff0c;保持账户余额充足是确保服务不中断的关键。下面&#xff0c;九河云将详细讲解具体的操作步骤。 步骤一&#xff1a;登录AWS管理控制台 首先&#xff…...

(六十四)第 10 章 内部排序(静态链表的插入排序)

示例代码 staticLinkList.h // 静态链表的插入排序实现头文件#ifndef STATIC_LINK_LIST_H #define STATIC_LINK_LIST_H#include "errorRecord.h"#define SIZE 100 #define NUM 8typedef int InfoType; typedef int KeyType;typedef struct {KeyType key;InfoType inf…...

appium历史版本地址链接

appium / Appium.app / Downloads — Bitbucket ios的appium界面图 链接: https://pan.baidu.com/s/1i8BRaZgQA3ImLUhKZjfhiA 提取码: 5c8b...

TCPIP网络编程(尹圣雨)UDP 轮流收发消息(windows)

端口号写的是 2345 客户端 #include <iostream> #include <winsock2.h> #pragma comment(lib, "ws2_32.lib")using std::cout; using std::endl; using std::cin;int main() {WSADATA wsa;if (WSAStartup(MAKEWORD(2, 2), &wsa) ! 0){cout <<…...

【相机方案(2)】V4L2 支持相机图像直接进入GPU内存吗?DeepStream 确实可以将图像数据高效地放入GPU内存进行处理!

V4L2 支持相机图像直接进入GPU内存吗&#xff1f; V4L2&#xff08;Video4Linux Two&#xff09;是Linux内核中用于视频捕获和播放的API&#xff0c;它本身并不直接支持将相机捕获的图像数据直接拷贝到GPU内存而不经过CPU内存。V4L2主要关注于视频设备的控制、数据的捕获和播放…...

UEFI——PEI阶段

一、PEI介绍 Pre-EFI Initialization&#xff08;PEI&#xff09;在引导的早期被调用&#xff0c;仅利用CPU资源调用PEIM&#xff0c;这些PEIM负责&#xff1a; &#xff08;1&#xff09;初始化一些永久内存 &#xff08;2&#xff09;在HOBs中描述内存信息 &#xff08;3…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

重启Eureka集群中的节点,对已经注册的服务有什么影响

先看答案&#xff0c;如果正确地操作&#xff0c;重启Eureka集群中的节点&#xff0c;对已经注册的服务影响非常小&#xff0c;甚至可以做到无感知。 但如果操作不当&#xff0c;可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生&#xff0c;小白用户&#xff0c;想学习知识的 有点基础&#xff0c;想要通过项…...