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

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

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

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

第一种:无可置疑是递归

核心代码块:

/*求二叉树的深度 ,递归方式*/

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

#include

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

相关推荐

荣耀 8参数对比
365bet网站

荣耀 8参数对比

📅 06-30 👁️ 9610
极速推推广最佳时间是什么?效果评估与实际作用分析
beat365中国在线体育

极速推推广最佳时间是什么?效果评估与实际作用分析

📅 07-17 👁️ 6956
给佛像拍照,真的会触犯禁忌吗?
365bet网站

给佛像拍照,真的会触犯禁忌吗?

📅 07-05 👁️ 3854
生根粉泡根要多久,如何提高扦插的成活率?
365买球官网入口

生根粉泡根要多久,如何提高扦插的成活率?

📅 07-16 👁️ 9400
神武2手游存珍兽攻略 神武2手游里面珍兽怎么进阶
绝地求生账号怎么改邮箱
beat365中国在线体育

绝地求生账号怎么改邮箱

📅 06-27 👁️ 6096
一台全自动洗车机究竟要多少钱
beat365中国在线体育

一台全自动洗车机究竟要多少钱

📅 07-12 👁️ 8956
dnf魔枪士四职业哪个好?魔枪士职业选择推荐
365买球官网入口

dnf魔枪士四职业哪个好?魔枪士职业选择推荐

📅 07-11 👁️ 6218
倪大红和倪萍什么关系 两个人是亲戚吗
beat365中国在线体育

倪大红和倪萍什么关系 两个人是亲戚吗

📅 07-06 👁️ 9643