一、二叉树的遍历
在链式二叉树的定义与实现中我们已经详细讲解了二叉树常见的三种遍历方式,以及层序遍历,这里给出链接:【初阶数据结构与算法】二叉树链式结构的定义与实现万字笔记(附源码)
放在这里是希望大家可以通过题目链接去练习一下,看看自己能不能写出来,写不出来再去上文复习复习,链接如下:
前序遍历:https://leetcode.cn/problems/binary-tree-preorder-traversal/description/
中序遍历:https://leetcode.cn/problems/binary-tree-inorder-traversal/description/
后序遍历:https://leetcode.cn/problems/binary-tree-postorder-traversal/description/
二、单值二叉树
题目链接:https://leetcode.cn/problems/univalued-binary-tree/description/
我们先来看看题目描述以及相关示例:
这道题要求我们查看一颗二叉树里面所有节点存放的值是否相同,比较简单,相当于考察我们的链式二叉树中递归的学习,以及对遍历的理解,可以自己先尝试着做一做,然后再来看后面的解析和答案
首先我们来说解析,这个题我们还是需要使用递归的思想,就是“以大化小”,将大的问题转化为一个又一个的子问题,按照这种思路我们来重新解释一下这道题:
首先看根节点和左右子树根节点是否相同,如果相同就看左右子树是否同时为单值二叉树,我们就将这个大问题转化为了根节点和左右子树根节点的比较,以及左右是否为单值二叉树这样的小问题
或者说这样理解也可以,就是这道题需要我们遍历整颗二叉树,在我们遍历整颗二叉树时,每遍历一个节点就判断一下当前节点和它的左右孩子是否相等,当然,在这之前我们需要判断左右孩子是否存在
相当于就是根节点和它的左右孩子的值作比较,然后根节点的左右孩子也有自己的左右孩子,让它们的左右孩子继续和自己的左右孩子进行比较,这样就相当于在递归,跟我们的遍历很相似
但是最后我们发现这两个思路是高度重合的,甚至可以说就是一个思想说了两遍,但是不管怎样,我们对单值二叉树有了更深的了解,接下来来说说具体做法
首先我们需要判断根节点是否为空,如果为空就返回true,如果不为空的话,先判断左右孩子是否为空,跟不为空的孩子做比较,如果发现某个孩子的值和根节点不同,就返回false
如果和左右孩子比较后发现相同就去递归左右孩子,将整颗子树是否是单值二叉树问题转化为左子树和右子树是否同时为单值二叉树这样的递归思想,那么有了思路我们就来写代码,如下:
bool isUnivalTree(struct TreeNode* root)
{
//首先判断根节点是否为空,为空返回true
if(root == NULL)
{
return true;
}
//如果左孩子不为空,看看左孩子和根节点是否相同,不同就返回假
if(root->left && root->left->val != root->val)
{
return false;
}
//如果右孩子不为空,看看右孩子和根节点是否相同,不相同就返回假
if(root->right && root->right->val != root->val)
{
return false;
}
//递归左右子树
bool left = isUnivalTree(root->left);
bool right = isUnivalTree(root->right);