【初阶数据结构】 左右逢源的分支诗律 二叉树2

📖 点击展开/收起 文章目录

文章目录

1.二叉树经典问题

在上期我们主要讲了二叉树的性质定义等基础,然而二叉树的核心是递归 ,在本期的题目分享中有大量递归实现,相信聪明的你,看完这些题目,递归思想会更上一层楼,当然看完后自己实现更好,掌握更加牢靠

话不多说直接上题目

1. 二叉树结点个数

思路: 递归左子树结点个数+右子树节点个数

注意:返回时左右子树节点和+1才是新的子树节点数

c 复制代码
int TreeSize(BTNode* root)
{
    return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}

2. 二叉树的高度

思路: 递归左子树高度,右子树高度,取较大值+1,替代新的子树大小
这里我们设置了两种返回情况,一种是遇到空节点,一种是叶子节点

注意:新的子树大小要将他的子树高度+1才是他本是的高度

c 复制代码
int BTHeight(BTNode*root)
{
    if (root == NULL)//空节点
    {
        return 0;
    }
    if (root->left==NULL&&root->right==NULL)//只有他一个节点的时候返回高度1,高度就是让它本身
    {
        return 1;
    }
        int lefth = BTHeight(root->left);
        int righth = BTHeight(root->right);
        return lefth > righth ? lefth + 1 : righth + 1;
}

3. 二叉树叶子结点个数

思路: 递归左子树叶子节点+右子树叶子节点,叶节点无子节点

注意:仍然要处理空节点情况,因为我们递归终止条件是,空节点,和叶节点两种情况,遇到只有一棵子树时,空子树就返回0

c 复制代码
int BTLeaf(BTNode*root)
{
    if (root == NULL)
    {
        return 0;
    }
    if (root->left == NULL && root->right == NULL)
    {
        return 1;
    }
    return  BTLeaf(root->left) + BTLeaf(root->right);
}

4. 二叉树第k层结点个数

思路: 找子树的k-1层节点数,找子树的子树的k-2层.......

注意:有两种返回条件,第一种k=1,直接返回1,如果走不到k=1就没节点了,直接返回0

c 复制代码
int LeafKNodeNum(BTNode*root,int k)
{
    if (root == NULL)
    {
        return 0;
    }
    if (k == 1)
    {
        return 1;
    }
  return  LeafKNodeNum(root->left, k - 1)+LeafKNodeNum(root->right, k - 1);
}

5. 二叉树查找值为x的结点

思路: 在根节点找,再去左子树找,再去右子树找,以子树查找时,把子节点有当作根节点去查找

注意:查找的先后顺序不能乱了

c 复制代码
BTNode*  FindTree(BTNode*root,int x)
{
	if (root == NULL)
	{
		return NULL;
	}
	if (root->val == x)
	{
		return root;
	}
	BTNode* ret1 = FindTree(root->left, x);
	if (ret1)
	{
		return ret1;
	}
	BTNode* ret2 = FindTree(root->right, x);
	if (ret2)
	{
		return ret2;
	}
	return NULL;
}

总结:

在前面几个递归训练中,我们发现二叉树问题代码都不复杂,复杂的是分解子问题和找递归停止条件
因此我们拿到题目,先进行子问题分解,再思考递归终止条件,而做这些最重要的就是画图理清思路

2.二叉树经典OJ

我会把每一题OJ链接放在讲解前面,大家可自行去尝试解答加强训练,和印象

1. 单值二叉树

OJ单值二叉树
题目描述 :如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。

只有给定的树是单值二叉树时,才返回 true;否则返回 false。
思路: 如果是单值二叉树,那他的左右子树也是单值二叉树
注意: 检查二叉树的前提是该节点存在

c 复制代码
bool IsUnivaluedBT(BTNode* root)
{
    if (root == NULL)
    {
        return true;
    }
    //证明为单值二叉树太麻烦,我们就找不为单值二叉树的情况
    if (root->left && root->left->data !=root->data)
    {
        return false;
    }
    if (root->right && root->right->data != root->data)
    {
        return false;
    }
    return IsUnivaluedBT(root->left) && IsUnivaluedBT(root->right);
}

2. 检查两颗树是否相同

OJ检查两棵树是否相同
题目描述 :给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
思路: 如果是两颗完全相同的树,那他的根节点要相同,左子树和右子树要相同,又以左右子树根节点为根节点来检查
注意: 进去先要检查两棵树,该节点是否同时存在,先要检查的就是根节点是否相同

c 复制代码
bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
  //注意这种简洁的处理方式,如果他们不是&&关系,他们又是||关系,那么就必定是有一个节点存在一个节点不存在
  //如果两个节点存在,逻辑就不会进入||,就会继续往下走
    if (p == NULL && q == NULL)
    {
        return true;
    }
    if (p == NULL || q == NULL)
    {
        return false;
    }
    if (p->val == q->val)
        return isSameTree(q->left, p->left) && isSameTree(q->right, p->right);
    else
        return false;
}

3. 对称二叉树

OJ对称二叉树
题目描述 :给你一个二叉树的根节点 root , 检查它是否轴对称。
思路: 可以继承上面找相同的树的方法,把左子树可左子树相同,换成左子树与右子树相同,右子树与左子树相同,根节点相同
注意: 进去先要检查两棵树,该节点是否同时存在,先要检查的就是根节点是否相同

c 复制代码
bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
    if (p == NULL && q == NULL)
    {
        return true;
    }
    if (p == NULL || q == NULL)
    {
        return false;
    }
    if (p->val == q->val)
        return isSameTree(q->left, p->right) && isSameTree(q->right, p->left);
    else
        return false;
}
bool isSymmetric(struct TreeNode* root) {
   return isSameTree(root->left,root->right);
}

4. 另一棵树的子树

OJ另一棵树的子树
题目描述 :给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。

二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。

***思路:***我们的思路就是,在左右子树中间找值与subroot根节点值相同的节点然后调用Issametree判断是否是子树

如果是false就接着找,如果左子树没有,就去右子树找,都没有就返回false

c 复制代码
bool Issametree(struct TreeNode* root, struct TreeNode* subRoot)
{
    if(root==NULL&&subRoot==NULL)
    {
        return true;
    }
    if(root==NULL||subRoot==NULL)
    {
        return false;
    }
  if(root->val==subRoot->val)
    {
        return Issametree(root->left, subRoot->left)&&Issametree(root->right, subRoot->right);
    }
    else
    return false;
}
bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot) {
    if(root==NULL)
    {
        return false;
    }
    if(root->val==subRoot->val)
    {
         bool ret =Issametree(root,subRoot);
         if(ret==true)
         {
            return true;
         }
    }
        return isSubtree( root->left,subRoot)||
        isSubtree(root->right,subRoot); 
}

我将二叉树的遍历,销毁,创建,等等反倒下一期不然篇幅太大了

希望读者们多多三连支持

小编会继续更新

你们的鼓励就是我前进的动力!

相关推荐
AZaLEan__1 小时前
算法考核题解
算法
MediaTea1 小时前
AI 术语通俗词典:ID3 算法
人工智能·算法
Morwit1 小时前
【力扣hot100】 221. 最大正方形
前端·算法·leetcode
呃呃本2 小时前
算法题(矩阵)
线性代数·算法·矩阵
2301_789015622 小时前
Linux基础指令(一)
linux·运维·服务器·c语言·开发语言·c++·linux指令
呃呃本2 小时前
算法题(普通数组、矩阵)
线性代数·算法·矩阵
计算机安禾2 小时前
【计算机网络】第11篇:链路状态路由协议——Dijkstra算法与OSPF的分区架构
计算机网络·算法·架构
珂朵莉MM2 小时前
第七届全球校园人工智能算法精英大赛-算法巅峰赛产业命题赛第二赛季优化题--遗传算法
人工智能·算法
gihigo19982 小时前
严格耦合波分析计算光栅衍射效率算法
算法