二叉树创建和遍历

|--------------------------------------------------------------------------------------------------------------------------------|
| 个人主页 :敲上瘾-CSDN博客 |
| 二叉树介绍:二叉树(详解)-CSDN博客 |

目录

一、二叉树的创建

二、二叉树的遍历

1.前序遍历

2.中序遍历

3.后序遍历

4.层序遍历

三、相关计算

1.总节点个数计算

2.叶子节点个数计算

3.深度计算


一、二叉树的创建

关于二叉树的创建和遍历我们考虑用递归来实现。

我们通过前序遍历的数组"ABD##E#H##CF##G##" 来创建数组,其中 '#' 相当于空指针。

头文件的声明:

cpp 复制代码
typedef char BTDataType;

typedef struct BinaryTreeNode
{
	BTDataType _data;
	struct BinaryTreeNode* _left;
	struct BinaryTreeNode* _right;
}BTNode;
cpp 复制代码
BTNode* BinaryTreeCreate(BTDataType* a, int n, int* pi)
{
	if (*pi == n)
		return NULL;
	int val = a[(*pi)++];
	if (val == '#')
		return NULL;
	BTNode* root = (BTNode*)malloc(sizeof(BTNode));
	assert(root);
	root->_data = val;
	root->_left = BinaryTreeCreate(a, n, pi);
	root->_right = BinaryTreeCreate(a, n, pi);
	return root;
}

二、二叉树的遍历

学习二叉树结构,最简单的方式就是遍历。所谓二叉树遍历(Traversal)是按照某种特定的规则,依次对二叉树中的结点进行相应的操作,并且每个结点只操作一次。访问结点所做的操作依赖于具体的应用问题。

遍历是二叉树上最重要的运算之一,也是二叉树上进行其它运算的基础。

按照规则,二叉树的遍历有:前序/中序/后序的递归结构遍历:

  1. 前序遍历(Preorder Traversal 亦称先序遍历)------访问根结点的操作发生在遍历其左右子树之前。

  2. 中序遍历(Inorder Traversal)------访问根结点的操作发生在遍历其左右子树之中(间)。

  3. 后序遍历(Postorder Traversal)------访问根结点的操作发生在遍历其左右子树之后。

由于被访问的结点必是某子树的根,所以N(Node)、L(Left subtree)和R(Right subtree)又可解释为根、根的左子树和根的右子树。NLR、LNR和LRN分别又称为先根遍历、中根遍历和后根遍历。

1.前序遍历

cpp 复制代码
void BinaryTreePrevOrder(BTNode* root)
{
	if (!root)
	{
		printf("#");
		return;
	}
	printf("%c", root->_data);
	BinaryTreePrevOrder(root->_left);
	BinaryTreePrevOrder(root->_right);
}
//或者这么写:
void PrevOrder(BTNode* root)
{
	if (root)
	{
    	printf("%c", root->_data);
    	PrevOrder(root->_left);
	    PrevOrder(root->_right);
    }
}

2.中序遍历

cpp 复制代码
void BinaryTreeInOrder(BTNode* root)
{
	if (!root)
	{
		printf("#");
		return;
	}
	BinaryTreeInOrder(root->_left);
	printf("%c", root->_data);
	BinaryTreeInOrder(root->_right);
}

3.后序遍历

cpp 复制代码
void BinaryTreePostOrder(BTNode* root)
{
	if (!root)
	{
		printf("#");
		return;
	}
	BinaryTreePostOrder(root->_left);
	BinaryTreePostOrder(root->_right);
	printf("%c", root->_data);
}

4.层序遍历

层序遍历是一层一层往下遍历的,并不是单个方向深入,像以上三种遍历都可以叫做深度优先遍历 ,而层序遍历也可以叫做广度优先遍历 ,它是不能用递归实现的,要实现它我们可以使用一个队列结构,我们把根节点存入队列然后对队列进行操作,把根节点拿出来(Pop)然后把它的左孩子和右孩子依次取出放入队列,然后再次从队头取到根节点重复操作,一次下去直到队列为空,就能完成层序遍历。如下:

cpp 复制代码
void BinaryTreeLevelOrder(BTNode* root)
{
	if (!root)
		return;
	Queue pt;//需要构造出一个队列结构,这里就不在展示
	QueueInit(&pt);
	QueuePush(&pt, root);
	while (!QueueEmpty(&pt))
	{
		BTNode* pf = QueueFront(&pt);
		if (pf)
			printf("%c", pf->_data);
		else
			printf("#");
		QueuePop(&pt);
		if (pf)
		{
			QueuePush(&pt, pf->_left);
			QueuePush(&pt, pf->_right);
		}
	}
}

三、相关计算

1.总节点个数计算

在计算节点个数的时候,初学着可能会想用一个全局变量,用以上任意方法遍历并计数。这种方法是可行的但不太可靠。像这些二叉树相关的计算我们大多数都可以考虑把它化为小问题去分析。如果是空树的话就是0,如果不是空树就是1+左树的节点个数+右树的节点个数,像这样左树又可以分为左树和右树去解决,可以不断的把问题化小。如下:

cpp 复制代码
int BinaryTreeSize(BTNode* root)
{
	if (!root)
		return 0;
	else
		return BinaryTreeSize(root->_left) + BinaryTreeSize(root->_right) + 1;
}

2.叶子节点个数计算

这个计算和上一个方法是相似的,不过我们得特别判断以下是否为叶子节点。如下:

cpp 复制代码
int BinaryTreeLeafSize(BTNode* root)
{
	if (!root)
		return 0;
	if (!root->_left && !root->_right)
		return 1;
	return BinaryTreeLeafSize(root->_left) + BinaryTreeLeafSize(root->_right);
}

3.深度计算

求一颗树的深度可以化为就是左子树的深度和右子树中的最大深度,而左子树又可以在化为更小的左右子树的深度就如此递推下去,直到遇到空树才一次回归(返回),这样就把大问题化为小问题用递归实现。如下:

cpp 复制代码
int BinaryTreeHeight(BTNode* root)
{
	if (!root)
		return 0;
	int v1=BinaryTreeHeight(root->_left);
	int v2 = BinaryTreeHeight(root->_right);
	return v1 > v2 ? v1 + 1 : v2 + 1;
}

要注意一点的是千万不要写成下面的方式:

这样会使一个函数内就有三个递归展开,效率会变得非常非常低。

相关推荐
钢铁男儿4 分钟前
C# 类和继承(扩展方法)
java·servlet·c#
饮长安千年月10 分钟前
JavaSec-SpringBoot框架
java·spring boot·后端·计算机网络·安全·web安全·网络安全
移动开发者1号11 分钟前
Android 大文件分块上传实战:突破表单数据限制的完整方案
android·java·kotlin
代码匠心12 分钟前
从零开始学Flink:揭开实时计算的神秘面纱
java·大数据·后端·flink
jie1889457586627 分钟前
C++ 中的 const 知识点详解,c++和c语言区别
java·c语言·c++
网安INF32 分钟前
RSA加密算法:非对称密码学的基石
java·开发语言·密码学
明月*清风33 分钟前
c++ —— 内存管理
开发语言·c++
蔡蓝37 分钟前
设计模式-观察着模式
java·开发语言·设计模式
异常君1 小时前
@Bean 在@Configuration 中和普通类中的本质区别
java·spring·面试
jackson凌1 小时前
【Java学习笔记】Math方法
java·笔记·学习