编写算法求出二叉树的深度(层数)


二叉树的深度是指从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。本文将用两种方式求出二叉树的深度

第一种:无可置疑是递归

核心代码块:

/*求二叉树的深度 ,递归方式*/
int getDepth(BiTreeNode *root)
{int left, right;if (root == NULL)    //递归出口return 0;else{left = getDepth(root->leftChild);    //递归right = getDepth(root->rightChild);return left > right ? (left+1) : (right+1);   //返回较深的一棵子树}
}

源文件:《main.c》

#include"BiTree.h"
#include"Domin.h"
int main()
{/*测试二叉树*/BiTreeNode *root, *p;initiateBiTree(&root);p = leftInsert(root, 'A');p = leftInsert(p, 'B');leftInsert(p, 'D');rightInsert(p, 'E');p = rightInsert(root->leftChild, 'C');leftInsert(p, 'F');rightInsert(p, 'G');printf("二叉树前序遍历:");preOrder(root->leftChild);printf("\n");printf("二叉树中序遍历:");midOrder(root->leftChild);printf("\n");printf("该二叉树的深度为:");printf("%d \n", getDepth(root->leftChild));system("pause");return 0;
}

测试结果:

上方主函数中建立的二叉树,结果如下:


测试一:深度为3


对主函数稍作修改

建立下方形状的二叉树,有


测试二:深度为2


第二种:利用队列层序遍历

思想步骤:

1. 将根结点入队,当前队列中第一层的结点数(count)为1;

2. 进行当前层结点数(count)次出队,判断每个结点的左右子树是否为空,如果不为空,则入队,下一层结点数(nextCount)++;

3. 将下一层结点数变为当前层结点数,进行下一次循环,深度+1;

4. 直到队列为空时退出循环,得到最大深度;

核心代码块:

//求二叉树的深度,非递归方式
int getDepth(BiTreeNode *root)
{if (root == NULL)return 0;Queue queue, *p;p = &queue;initiateQueue(p);int depth = 0, count = 1,nextCount = 0;    //该层中结点的个数,下一层结点的个数queueAppend(p, root);                     //根结点入队BiTreeNode *temp = (BiTreeNode*)malloc(sizeof(BiTreeNode));while (isNotEmpty(p))   //队列不为空时一直循环{depth++;            //每进入一次循环,就代表开始进入下一层for (int i = 0; i < count; i++){queuePop(p, temp);if (temp->leftChild!=NULL) {    //添加非空结点queueAppend(p, temp->leftChild);nextCount++;}if (temp->rightChild!=NULL) {queueAppend(p, temp->rightChild);nextCount++;}}count = nextCount;   //即将进行出队下一层结点,下一层结点数成为当前层结点数nextCount = 0;       //将下一层结点从0开始计数}return depth;
}

完整测试代码如下:

注:实例测试由4个文件构成:《BiTree.h》《Domin.h》《Queue.h》《main.c》,第二种方式核心代码块放在《Domin.h》头文件内

《BiTree.h》

#pragma once
/*二叉树基本操作头文件*/
#include<stdio.h>
#include<stdlib.h>
typedef char DataType;   //声明数据类型
struct  BiTreeNode
{DataType data;BiTreeNode *leftChild;BiTreeNode *rightChild;
};
//初始化二叉树
void  initiateBiTree(BiTreeNode **root)
{(*root) = (BiTreeNode*)malloc(sizeof(BiTreeNode));(*root)->leftChild = NULL;(*root)->rightChild = NULL;
}
//插入左孩子结点
BiTreeNode* leftInsert(BiTreeNode *curr, DataType data)
{if (curr == NULL)return NULL;BiTreeNode *node = (BiTreeNode*)malloc(sizeof(BiTreeNode));node->data = data;node->rightChild = NULL;node->leftChild = curr->leftChild;curr->leftChild = node;return node;
}
//插入右孩子结点
BiTreeNode* rightInsert(BiTreeNode *curr, DataType data)
{if (curr == NULL)return NULL;BiTreeNode *node = (BiTreeNode*)malloc(sizeof(BiTreeNode));node->data = data;node->leftChild = NULL;node->rightChild = curr->rightChild;curr->rightChild = node;return node;
}
//前序遍历二叉树
void preOrder(BiTreeNode *root)
{if (root != NULL){printf("%c ", root->data);preOrder(root->leftChild);preOrder(root->rightChild);}
}
//中序遍历
void midOrder(BiTreeNode *root)
{if (root != NULL){midOrder(root->leftChild);printf("%c ", root->data);midOrder(root->rightChild);}
}

《Queue.h》

#pragma once
/*队列基本操作头文件*/
#include"BiTree.h"
typedef BiTreeNode queueDataType;
struct QueueNode
{queueDataType data;QueueNode *next;
};
struct Queue
{QueueNode *head;QueueNode *rear;
};
void initiateQueue(Queue *queue)
{queue->head = NULL;queue->rear = NULL;
}
/*判断非空*/
bool isNotEmpty(Queue* queue)
{if (queue->head == NULL)return false;return true;
}
/*入队函数*/
void queueAppend(Queue *queue, queueDataType *data)
{QueueNode *node = (QueueNode*)malloc(sizeof(QueueNode));if (data != NULL){node->data.data = data->data;node->data.leftChild = data->leftChild;node->data.rightChild = data->rightChild;}else {node->data.data = '0';       // 用0来标记要入队的结点是空的二叉树结点node->data.leftChild = NULL;node->data.rightChild = NULL;}node->next = NULL;if (queue->rear == NULL){queue->head = node;queue->rear = node;}else{queue->rear->next = node;queue->rear = node;}
}
/*出队函数*/
void queuePop(Queue*queue, queueDataType *data)
{if (!isNotEmpty(queue))return;*data = queue->head->data;queue->head = queue->head->next;if (queue->head == NULL)queue->rear = NULL;
}
/*取队头元素*/
void  getHead(Queue *queue,queueDataType *head)
{if (!isNotEmpty(queue))head = NULL;else*head = (queue->head->data);
}

《main.c》

#include"BiTree.h"
#include"Domin.h"
int main()
{/*测试二叉树*/BiTreeNode *root, *p;initiateBiTree(&root);p = leftInsert(root, 'A');p = leftInsert(p, 'B');leftInsert(p, 'D');rightInsert(p, 'E');p = rightInsert(root->leftChild, 'C');leftInsert(p, 'F');p = rightInsert(p, 'G');rightInsert(p, 'H');printf("二叉树前序遍历:");preOrder(root->leftChild);printf("\n");printf("二叉树中序遍历:");midOrder(root->leftChild);printf("\n");printf("该二叉树的深度为:");printf("%d \n", getDepth(root->leftChild));system("pause");return 0;
}

测试结果:

测试一:深度为4


将主函数稍作改变:

测试结果如下:


测试二:深度为3



代码编译器:Visual Studio 2017
ok

【代码+注释】求二叉树的深度【超详细】递归+非递归实现相关推荐

  1. Redis第二集:Linux下安装Redis和测试,包含命令代码和问题处理办法,超详细版

    Redis第二集:Linux下安装Redis和测试,包含命令代码和问题处理办法,超详细版 一.资源 Linux下的Redis的下载地址 二.安装与测试 上传至自己的Linux平台 解压安装包 tar ...

  2. 数据结构实验之二叉树八:(中序后序)求二叉树的深度

    Description 已知一颗二叉树的中序遍历序列和后序遍历序列,求二叉树的深度. Input 输入数据有多组,输入T,代表有T组数据.每组数据包括两个长度小于50的字符串,第一个字符串表示二叉树的 ...

  3. 求二叉树的深度和宽度

    // 求二叉树的深度和宽度.cpp : 定义控制台应用程序的入口点. <pre name="code" class="cpp">#include & ...

  4. 求二叉树的深度 题目编号:376

    求二叉树的深度 题目编号:376 题目描述 采用先序法建立一棵二叉树,设计求该二叉树的深度,二叉树的数据域类型为字符型,扩展二叉树的叶子结点用'#'表示,要求可以求多棵二叉树的深度,当二叉树的深度为0 ...

  5. JAVA 二叉树 常见操作合集(前中后序递归非递归遍历 层序遍历 求深度宽度 判断兄弟结点 堂兄弟节点)

    今天复习了二叉树的相关操作,整理归纳如下. 二叉树结点定义 //节点类private static class TreeNode{private int val = 0;private TreeNod ...

  6. 树与二叉树——递归算法、非递归算法求二叉树的深度

    二叉树的结构: typedef struct BTNode {ElemType data;struct BTNode *lchild, *rchild; } BTNode; 递归算法求二叉树的深度de ...

  7. 二叉树的深度(前序 中序 后序 递归非递归搜素)、广度、搜索 C++

    a b c 使用 1 2 3 表示 /* 描述:二叉树的深度(前序 中序 后序 递归非递归搜素).广度.搜索 作者:jz 日期:20140819 */ #include<stdio.h> ...

  8. 二叉树的深度(递归+非递归)

    递归实现基本思想: 为了求得树的深度,可以先求左右子树的深度,取二者较大者加1即是树的深度,递归返回的条件是若节点为空,返回0 算法: int FindTreeDeep(BinTree BT){int ...

  9. 二叉树先、中、后遍历递归+非递归

    文章目录 前言 思路 设计思想 非递归前序遍历的思路 非递归中序遍历的思路 非递归后序遍历的思路 层序遍历的思路 完整代码 MyBinaryTree.h MyBinaryTree.cpp Main.c ...

最新文章

  1. 多视图立体匹配论文分享:BlendedMVS
  2. 调用java_UiPath如何调用Java
  3. 使用C++与SFML编写一个简单的撞球游戏Part1——新建工程以及设置
  4. 再谈java乱码:GBK和UTF-8互转尾部乱码问题分析
  5. JSON.stringify()还可以这么用
  6. 领域驱动设计-什么是领域驱动设计和怎么使用它
  7. (三)git常用命令及方法大全
  8. 二级联动菜单ajax刷新,jquery json ajax 二级联动菜单实例
  9. mysql时间相减得到天数保留两位_【敲黑板!】分布式事务数据库 —-MySQL 数据库开发规范(第四节)...
  10. ThreadLocal原理解析以及是否需要调用remove方法
  11. Python学习笔记之文件
  12. 使用truffle 创建代币合约 使用ganache部署私有链 以及使用Atom 进行合约代码开发
  13. 不必写一行代码,利用ivx低代码产品开发web平台
  14. Alkyne-PEG2000-Maleimide,含有炔基和马来西安亚楠的PEG,Alk-PEG2000-MAL
  15. R语言入门——一文讲明白attach与detach
  16. 2021-2022上学期 奖状的清单
  17. 在线图片处理工具大全!ps可以下岗了。
  18. ppt如何变成pdf
  19. Qt+OpenGL实现三维地形显示
  20. python蓝牙编程代码_以编程方式通过python将蓝牙设备绑定到rfcomm

热门文章

  1. 5G还没来4G却变慢?专家称与提速降费有关
  2. 闲聊PMP证书及游戏规则
  3. python设计程序基础、李东方教材答案_Python程序设计基础(第2版)
  4. 微信小程序对企业,开发者,用户的影响有哪些?
  5. 使用python-opencv对双目摄像头进行立体视觉图像矫正,去畸变
  6. MBG基于java配置的环境搭建
  7. 词性标注实战(Part-Of-Speech tagging, POS tagging)
  8. text rank java 实现_使用TextRank实现的关键字提取
  9. TDH集群数据拷贝及元数据迁移
  10. 华为平板 M3 青春版评测:华丽视觉体验,十分靠谱