二叉树练习题(递归展开图详解哦)

引言

前面我们介绍了二叉树的相关基础知识,并且了解到二叉树的表示有两种结构:顺序结构与链式结构。即,使用顺序表或链表来表示二叉树:
戳我看二叉树详解哦

在上一篇文章中,我们了解了二叉树的顺序访问(也就是堆),以及其接口实现:
戳我看堆及接口实现哦

在这篇文章中要介绍二叉树的链式访问,但是由于链表结点是难以随意访问二叉树中的结点的,用链式的二叉树进行增删查改其实是没有多少意义的。在本篇文章中就介绍几道二叉树链式结构的题目:单值二叉树、二叉树的最大深度、翻转二叉树、相同的树:

由于链式二叉树的节点结构,所以它具有很好的递归特性,在本篇文章中也会详细的画出递归展开图来说明:

typedef int BTDataType;
struct BinaryTreeNode
{
    
    
    struct BinTreeNode* _pLeft; // 指向当前节点左孩子
    struct BinTreeNode* _pRight; // 指向当前节点右孩子
    BTDataType _data; // 当前节点值
}

单值二叉树

单值二叉树OJ链接

题目描述及思路

在这里插入图片描述
我们需要实现函数判断二叉树中的值是否全部相等,相等返回true,否则返回false。

我们可以递归:
每次递归判断本结点与其左右孩子结点的值是否相等,相等向上一级返回真,否则返回假;
如果遇到本结点为NULL则该条线的递归结束,向上一级返回真;
本结点判断完,若为真,继续向下递归,否则直接返回假;

向上一级返回时,要本结点的左右孩子结点分别返回真时才为真,所以返回它的左右孩子向其返回的值的逻辑与的结果。

实现

首先判断root是否为NULL,若为NULL直接返回true;
如果本结点的值与其左右孩子的值不相等,直接返回false;
相等后,再将其左右孩子结点作为根结点root,分别递归,返回他们返回的值的逻辑与的结果:

bool isUnivalTree(struct TreeNode* root)
{
    
    
	if (root == NULL)
	{
    
    
		return true;
	}
	if ((root->left && root->left->val != root->val)||(root->right && root->right->val != root->val))
	{
    
    
		return false;
	}
	else
	{
    
    
		return isUnivalTree(root->left) && isUnivalTree(root->right);
	}
}

递归展开图(由于函数代码有点长,画图时只写出函数名和返回值部分):
在这里插入图片描述

二叉树的最大深度

二叉树的最大深度OJ链接

题目描述及思路

在这里插入图片描述
我们需要实现函数,求出二叉树的最大深度。

我们可以递归:
每次递归计算本结点的左右子树的深度;
然后比较左右子树的深度,较大值+1就是本结点的深度,返回这个值给上一级。

实现

这道题的实现较为简单:

首先判断本结点是否为NULL,若为空直接返回0;
然后分别计算并存储左右子树的深度;
最后返回左右子树较大者+1的值:

需要注意的是,计算出左右子树的深度后,要将结果存储,否则会严重影响效率。

int maxDepth(struct TreeNode* root) 
{
    
    
	if (root == NULL)
	{
    
    
		return 0;
	}
	int lefthigh = maxDepth(root->left);
	int righthigh = maxDepth(root->right);

	return lefthigh > righthigh ? lefthigh + 1 : righthigh + 1;
}

递归展开图(省略判断NULL的部分):
在这里插入图片描述

翻转二叉树

翻转二叉树OJ链接

题目描述及思路

在这里插入图片描述
我们需要实现函数,实现二叉树左右结点的翻转。

我们知道,二叉树的每一个结点中包括本结点的值与两个孩子结点的指针,所以我们只需要递归实现将每一个结点的左右孩子结点的指针交换即可:

实现

首先判断本结点是否为NULL,若为空返回NULL;
然后交换两个孩子结点的指针;
然后分别将左右孩子为参数递归;
最后向上一级返回本结点的指针即可:

struct TreeNode* invertTree(struct TreeNode* root)
{
    
    
	if (root == NULL)
	{
    
    
		return NULL;
	}
	struct TreNode* temp = root->left;
	root->left = root->right;
	root->right = temp;

	invertTree(root->left);
	invertTree(root->right);
	return root;
}

递归展开图:
在这里插入图片描述

相同的树

相同的树OJ链接

题目描述及思路

在这里插入图片描述
我们需要实现函数判断两个二叉树是否相同,相等返回true,否则返回false。

我们可以递归判断每个结点的本身与其左右孩子结点是否分别相等:
判断时,可以只判断本结点的值是否相等;
若本结点相等,则向下递归,返回左右子结点返回的值逻辑与的结果。

实现

首先判断p与q是否为空,若均为空,则返回真;
若不是全为空,但有其中一个为空,则说明不像等,则返回假;
然后判断本结点的值是否相等,若不相等返回假;
若相等,将两树的左右结点分别递归,返回他们返回的值的逻辑与的结果:

bool isSameTree(struct TreeNode* p, struct TreeNode* q) 
{
    
    
	if (p == NULL && q == NULL)
	{
    
    
		return true;
	}
	else if (p == NULL || q == NULL)
	{
    
    
		return false;
	}
	if(p->val!=q->val)
	{
    
    
		return false;
	}
	else
	{
    
    
		return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
	}
}

递归展开图(省略判断部分):
在这里插入图片描述

总结

到此,关于链式二叉树的几道OJ练习题就介绍到这里了

如果大家认为我对某一部分没有介绍清楚或者某一部分出了问题,欢迎大家在评论区提出

如果本文对你有帮助,希望一键三连哦

希望与大家共同进步哦

猜你喜欢

转载自blog.csdn.net/weixin_73450183/article/details/130027320
今日推荐