计算二叉树深度算法(递归、非递归)入门详解

article/2025/11/11 1:42:57

一、引言
二叉树在应用时,经常需要知道二叉树的深度。二叉树的深度就是二叉树的层数,即从树根算起,到最底下一层的层数是多少,即二叉树中结点的最大层次值。
本文给出了计算二叉树深度的算法,包括递归算法和非递归算法。
二、计算二叉树的基本方法
如下图所示的二叉树,其深度是4。
在这里插入图片描述
说到层数,大家自然会想到二叉树的层次遍历法。没错,其实我们只要一层一层的来遍历二叉树,当遍历到每一层的最右侧结点时,一层就遍历结束,因此可以考虑把每一层的最右侧结点作为每一层的标志,每当访问到该结类点时,二叉树的层数就可以增加1。
现在就会遇到一个问题:如何识别每一层最右侧的结点呢?
这时得回忆一下层次遍历算法,使用了队列来缓存二叉树上全部的结点,当初并没有识别每一层的最右侧结点。但是我们在层次遍历的过程中会发现,队列的队首总会走到每一层最右侧的结点位置,因此可以考虑通过判断队首的位置来识别最右侧结点,进而就可以得到层数。而且大家还会发现一个结论,那就是每一层最右侧的结点的左或者右子树也可能是下一层的最右侧结点(层尾结点)。当发现了这个结论,那么计算二叉树的深度就变得轻而易举了。
下面以上图为例演示一下按照层次遍历时,来识别二叉树深度的过程。
Step 1:树根a进队列,队列状态如下图所示:
在这里插入图片描述Step 2:队首出队列,队列状态如下图所示:
在这里插入图片描述
此时队首和队尾指向了同一个位置,也就是第一层遍历结束了,之后访问出队列的元素,并判断其左右子树是否为空,不空则继续入队列,所以就得到如下图所示的队列:
Step 3:结点a的左、右结点入队列
在这里插入图片描述
此时,其实我们又发现了:rear指向了队尾的前一个位置,就是一层结束的位置,如果在此处设个标志,是否可行?我们接着往下看。
Step 4:队首继续出队列、访问,访问之后,其左右子树非空的话,则继续入队列。
在这里插入图片描述当连续两次队首出队列之后,队列状态如上图所示,这是就会发现front的位置和新增加的标志位置相同了,这是其实又是一层的结束位置。
到这里,是不是就可以发现,引入这个标志的用处了?
因为当前层最后一个结点,它的左子树或者右子树也基本上就是下一层的最后一个结点,当然了如果当前层的最右侧结点的左右子树同时为空,则也可能是再左侧一些的结点是下一层的队尾(如图中所示的结点g就不是上一层尾结点的子树)。因此,我们在设定了当前层最右侧标志之后,则该最右侧结点的左或右子树入队列后的队尾,是不是就可能是新的标志位了?对头,就是这样的。
所以当某个结点的左右子树入队列的时候,队尾就可能是一层的结束位置。这也就是为什么在算法中是执行了某个结点的左右子树都入队列之后才判断是否是一层的结束了。(说的好像有点啰嗦了,原谅我)
进而只需要判断队首front的值和新增加的标志(不妨记为levelLoc)的值是否相同即可,相同则表示一层结束,总层数就可以加1了,同时把levelLoc的值更新为队列当前的队尾这是因为此时队尾可能就是上一层队尾的子树。
后面的步骤就不用再赘述了,直接上代码。
三、计算二叉树深度的源代码:
1、结点结构

typedef struct node
{char data;struct node *Lchild;struct node *Rchild;
}BiTree;

2、递归算法

int BiTreeDepth( BiTree *T )
{int dep1 = 0, dep2 = 0;if ( T == NULL )return 0;else{     dep1 = BiTreeDepth( T->Lchild );dep2 = BiTreeDepth( T->Rchild ); if ( dep1 > dep2 )  return dep1 + 1;else         return dep2 + 1;}
} 

3、非递归算法

int Search_Depth( BiTree *T)
{BiTree  *Queue[MAX_NODE]BiTree  *p = T;int  front=0 , rear=0, depth=0, levelLoc;// level总是指向访问层的最后一个结点在队列的位置if( T != NULL )Queue[++rear] = p;    //根结点入队levelLoc = rear;               //根是第1层的最后一个节点while ( front < rear ){p = Queue[ ++front ]; if ( p->Lchild != NULL )   Queue[ ++rear ] = p->Lchild; //左结点入队if ( p->Rchild != NULL )   Queue[ ++rear ] = p->Rchild; //右结点入队if ( front == levelLoc ) //访问到当前层的最后一个结点 {depth++;  levelLoc = rear; }}return depth;
}
  1. 配合使用创建二叉树的算法(参见二叉树专栏里的算法https://mp.csdn.net/mp_blog/manage/column/columnManage/11925622)就可以完整的运行了,此处不再赘述。

http://chatgpt.dhexx.cn/article/jmWb5VER.shtml

相关文章

计算二叉树的深度

[算法步骤] 如果是空树&#xff0c;递归结束&#xff0c;深度为0&#xff1b;否则执行一下操作 递归计算左子树的深度计为m;递归计算右子树的深度计为n;如果m大于n&#xff0c;二叉树的深度为m1&#xff0c;否则为n1&#xff1b; [算法描述] int Depth(BiTree T) {int m, n…

CreateDialog

使用对话框模版资源创建一个非模态对话框。 CreateDialog调用 CreateDialogParam 函数。 调用语序&#xff1a; HWND CreateDialog(HINSTANCE hInstance,LPCTSTR lpTemplate,HWND hWndParent,DLGPROC lpDialogFunc); 参数 hInstance类型&#xff1a;HINSTANCE 对话框模版…

android 使用showDialog调用相应的对话框

在Activity下调用此函数 showDialog(10); 然后重写以下函数 protected Dialog onCreateDialog(int id) {// TODO Auto-generated method stubswitch(id){case 10:return new AlertDialog.Builder(Activity13.this).setTitle(getString(R.string.title)).setMessage(getString(…

Show()跟ShowDialog()的区别

Show和ShowDialog有什么不同呢&#xff0c;什么时候用Show&#xff0c;什么时候用ShowDialog呢&#xff1f;相信看完这篇博客&#xff0c;你会有一个比较明确的答案。 说到show跟ShowDialog的区别很多人会想到的是&#xff0c;他们一个是非模态一个是模态&#xff0c;模态窗体就…

WPF Tips: Window.ShowDialog()方法:Cannot set Visibility or call Show, ShowDialog, or WindowInteropHelp

关于Window.ShowDialog()方法&#xff0c;有一个常见的容易犯的错误。下面给出这个错误的例子&#xff1a; DemoA&#xff1a;错误的例子 1. 在WPF项目中&#xff0c;创建一个Windows&#xff1a;DialogWindow DialogWindow.xaml <Window x:Class"DemoA.DialogWindow&…

showdialog

在C#中窗口的显示有两种方式&#xff1a;模态显示&#xff08;showdialog&#xff09;和非模态显示&#xff08;show&#xff09;。 区别&#xff1a; 模态与非模态窗体的主要区别是窗体显示的时候是否可以操作其他窗体。模态窗体不允许操作其他窗体&#xff0c;非模态窗体可以…

Flutter dialog (1) - showDialog的讲解

在应用开发中,或多或少都会遇到需要弹框的问题, 比如:需要用户确认,需要输入一些信息等等的问题,这就要用到 dialog 相关的概念了 而在 flutter 中,所有可以看见的都是 Widget,dialog 也不例外 不过和 android 或 iOS 中不同的一点是,Flutter 中 dialog 不是一个单独的类,而是…

C# 按Button弹出新的窗体 Show()方法 和 ShowDialog()方法

在做串口通信程序时&#xff0c;有个想法&#xff0c;当点击串口设置按钮时&#xff0c;弹出一个新的窗口&#xff0c;可以设置串口相关信息&#xff0c;如何实现这一操作呢&#xff1f; 1 新建一个项目&#xff0c;窗体为form1 2 选择项目名称&#xff0c;单击右键&#xff0…

C# 弹出窗口 show()和showdialog()

目录 一、构建工程和界面介绍二 、添加代码三、验证效果和小结 我们在构建C# Form窗口的时候经常需要到弹出新的窗口&#xff0c;那么接着就会如何弹出窗口的疑问。这里介绍最常见的两种弹窗方法show()和showdialog()。我在VS2019中构建一个简单的工程来讲解让他们之间的区别。…

fwrite函数,fread函数和fgets函数详解以及使用方法

c/c文件处理函数 1. fgets函数 函数原型 char *fgets(char *s, int size, FILE *stream);参数解释&#xff1a; s 代表要保存到的内存空间的首地址&#xff0c;可以是字符数组名&#xff0c;也可以是指向字符数组的字符指针变量名。size 代表的是读取字符串的长度。stream …

c语言 fread读指定字节,fread函数 c语言中fread函数怎么用

fread是一个函数,它从文件流中读数据,最多读取count个项,每个项size个字节,如果调用成功返回实际读取到的项个数(小于或等于count),如果不成功或读到文件末尾返回0。返回真实读取的项数,若大于count则意味着产生了错误。另外,产生错误后,文件位置指示器是无法确定的。若…

c语言fread函数,C语言“fread”函数的用法?

C语言“fread”函数的用法? C语言“fread”函数的用法为“size_tf read(void *buffer,size_t size,size_t count,FILE *stream)”,其作用是从一个文件流中读数据,读取count个元素,每个元素size字节。 示例1#include #include #include int main() {FILE *stream; char m…

【C 语言】文件操作 ( fread 函数 )

文章目录 一、fread 函数二、缓冲区受限的情况 ( 循环读取文件 | feof 函数判定文件读取完毕 )三、处理乱码问题四、记录读取的字节个数五、读取到 0 字节的情况六、读取完毕的情况七、读取文本文件 " " 与 读取二进制文件 " " 区别 二进制文件读写两个重…

Scala对象 转Json字符串

2019独角兽企业重金招聘Python工程师标准>>> import org.json4s.{Formats, NoTypeHints} import org.json4s.jackson.Serialization import org.json4s.jackson.Serialization.writeobject Json4sDemo {// 需要添加隐式转换implicit val formats: AnyRef with Forma…

【系统学习SpringBoot】SpringBoot 对象转JSON输出

SpringBoot输出JSON 以往使用SpringMVC中开发时&#xff0c;对象转JSON需要配置很多东西 【1】添加FastJson/jackjson等第三方jar 【2】在配置文件中配置Controller扫描 【3】给方法添加ResponseBody 配置FastJson还需要给配置文件中添加(很麻烦( ▼-▼ )) <mvc:annot…

【Java 笔记】使用Fastjson2时,对象转json首字母大小写问题

开发环境&#xff1a; Spring cloud Fastjson2 一、JSON 转 Object 推送第三方数据时&#xff0c;对方http接口消息体为json&#xff0c;但是字段首字母大写 我们需要接收JSON 转 Object [ { "ItemCode": "WIND_SPEED", "ItemValue": "2.1…

js 数组、对象转json 以及json转 数组、对象

1、JS对象转JSON 方式&#xff1a;JSON.stringify(obj) var json {"name":"iphone","price":666}; //创建对象&#xff1b; var jsonStr JSON.stringify(json); //转为JSON字符串 console.log(jsonStr);2、JS数组转JSON //数组转json…

对象转JSON首字母大写

最近在做一个第三方接口&#xff0c;接口给的数据类型如下 请求报文如下 {"A0144":"12141256","AB6AM":"中国银行支行","STATUS":1} 一般按照对象转JSON会使首字母小写&#xff0c;与接口文档不相符&#xff0c;因此需要…

Object对象转实体对象,java对象转json

Object对象转实体对象 在后台发起HTTP请求的时候&#xff0c;响应体传回的一般是Object或者JSON字符串。 方法一 要将Object对象转换成实体类对象可以先使用com.alibaba.fastjson.JSONObject类的toJSONString方法将Object对象转换成JSON字符串&#xff0c;然后再调用JSONObj…

对象 和 json 互转 四种方式 json-lib、Gson、FastJson、Jackson

文章目录 一、 json-lib二、 Google的Gson1.简介2. 配置步骤1. MAVEN 依赖引入2. gsonUtil 工具类3. 排除不要序列化的熟悉注解类 Exclude 三. 阿里巴巴的FastJson1.简介2.配置步骤1.引入maven2. 配置 CustomFastjsonConfig3. 测试 4. 开源的Jackson简介&#xff1a;Jackson配置…