【数据结构与算法】二叉树的综合运用--2

简介: 【数据结构与算法】二叉树的综合运用--2

【数据结构与算法】二叉树的综合运用--1https://developer.aliyun.com/article/1424484


二,判断单值二叉树

单值二叉树:二叉树的每个结点都具有相同的值。


分析:


       我们可遍历二叉树,并且每一个节点值都和根节点的值进行比对,如果不等于根节点的值,则不是单值树。


代码如下:


/**以下是二叉树的结构式
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
bool JudgeTree(struct TreeNode* root, int x) {
  if (!root) {
    return true;
  } 
  if (root->val != x) {
    return false;
  }
  //当有一个不满足条件时,一直返回的是false,最终结果也是false  
  return JudgeTree(root->left, x) && JudgeTree(root->right, x);
}
bool isUnivalTree(struct TreeNode* root) {
    if (!root) {
      return true;
    }
    return JudgeTree(root, root->val);
}


举一反三:


       当我们遇到像bool类型的二叉树算法时,可以像上述题型一样,系统给定函数的类型和参数与我们遍历思路不同时,可再创建一个返回类型和参数都令我们"满意的函数"。如以上题中系统给定的函数是bool isUnivalTree(struct TreeNode* root),参数令我们不满意,我们可创建一个函数:bool JudgeTree(struct TreeNode* root, int x),有个参数x以便后面我们比较。


       还有,像bool类型的函数一般不好在其中递归遍历,所以,当递归遍历时经常在返回值中运用逻辑运算符连接遍历。如以上题中return JudgeTree(root->left, x) && JudgeTree(root->right, x)。在此函数中用"&&"符号连接进行遍历,而具体使用哪个要根据情况而定,这方面还是要多加练习。


三,求二叉树的最大深度

题解:二叉树的最大深度是指从根节点到最远叶子节点的最长路径上的节点数。


分析:


       显然,本题也需要我们运用二叉树基础算法中的遍历算法。求解最大深度,我们可在递归遍历时记录在此函数中,以root为根结点左右孩子的总共数量,大的一方就是以此函数中root为根结点的子二叉树的最大深度,即当最终返回时,返回的是二叉树的最大深度。


代码如下:


/** 
 * 二叉树的结构
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
int maxDepth(struct TreeNode* root){
    if (!root) {
        return 0;
    }
    //记录左孩子的数量
    int leftsize = maxDepth(root->left) + 1;
    //记录右孩子的数量
    int rightsize = maxDepth(root->right) + 1;
    //返回以此递归函数中的子二叉树的最大深度
    return (leftsize > rightsize) ? leftsize : rightsize;
}


举一反三:


       本题要明白的是像类似于int leftsize = maxDepth(root->left) + 1和int rightsize = maxDepth(root->right) + 1以及最后return (leftsize > rightsize) ? leftsize : rightsize返回值与leftsize和rightsize的关联。leftsize是每次记录以此函数中root为根结点的子二叉树的左孩子结点个数加上1(加1是还包括根结点,即左孩子加上根结点的总个数),rightsize同理。最终返回的是此时子二叉树左孩子深度与右孩子深度的最大值。像此类的递归运用时,要思考运用递归的那一行与后面代码的中间逻辑关联。此关联多种多样,还需我们多多做题练习。


四,另一棵树的子树

题目:给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。其中,二叉树 tree 的一棵子树括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。


分析:


       显然,我们需要先遍历root这颗主树,当遇到结点数值与subRoot这颗树的根结点数值相同时就开始同时遍历这两颗树,判断这两颗树是否具有相同的逻辑和数值,如若在判断时这两个树在整个遍历过程中都有相同的逻辑和数值那么就返回true,否则就要继续往下面遍历root主树,当遍历完这颗root主树时返回false。


代码如下:


/** 二叉树的结构
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
 //设置此函数来进行判断root和subRoot两树结构和数值是否相等
 bool isSameTree(struct TreeNode* root1, struct TreeNode* root2) {
     if (!root1 && !root2) {
         return true;
     }
     if ((root1 && !root2) || (!root1 && root2)) {
         return false;
     }
     if (root1->val != root2->val) {
         return false;
     }
     return isSameTree(root1->left, root2->left) && isSameTree(root1->right, root2->right);
 }
 bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot) {
    //当两树同时或其中一颗为空时的情况 
    if (!root && !subRoot) {
         return true;
     }
     if (root && !subRoot) {
         return true;
     }
     //最终因为遍历时subRoot没有动,所以以次条件来判断返回false的情况
     if (!root && subRoot) {
         return false;
     }
     //如果当根结点的数值相等时,root就不会继续往下面递归遍历了,这时会出问题
     //例如:root中[1,1],subRoot中[1],运行时输出false,但实际上是true
     //下面的注释判断是根据直接思维判断,即重心在返回true上
     /*if (root->val == subRoot->val) {
         return isSameTree(root, subRoot);
     }*/
     //运用反向判断,即如果不满足时继续可往下进行
     if (root->val == subRoot->val) {
         if (isSameTree(root, subRoot)) {
             return true;
         }
     }
     //即只要找到与之匹配的情况时就结果就是true,用"||"控制这一点即可满足
     return isSubtree(root->left, subRoot) || isSubtree(root->right, subRoot);
 }

       具体的运用全部在解析中,重点放在条件的判断,要学会在以后的树中如何设定条件的判断。


学习建议:二叉树的运用是建立在二叉树基础算法之上,在学习到这一方面,必须要把二叉树的基本算法理解明白之后再上手。否则根基不稳后面会很吃亏。



相关文章
|
7天前
|
算法
分享一些提高二叉树遍历算法效率的代码示例
这只是简单的示例代码,实际应用中可能还需要根据具体需求进行更多的优化和处理。你可以根据自己的需求对代码进行修改和扩展。
|
10天前
|
存储 缓存 算法
如何提高二叉树遍历算法的效率?
选择合适的遍历算法,如按层次遍历树时使用广度优先搜索(BFS),中序遍历二叉搜索树以获得有序序列。优化数据结构,如使用线索二叉树减少空指针判断,自定义节点类增加辅助信息。利用递归与非递归的特点,避免栈溢出问题。多线程并行遍历提高速度,注意线程安全。缓存中间结果,避免重复计算。预先计算并存储信息,提高遍历效率。综合运用这些方法,提高二叉树遍历算法的效率。
29 5
|
14天前
|
C语言
【数据结构】二叉树(c语言)(附源码)
本文介绍了如何使用链式结构实现二叉树的基本功能,包括前序、中序、后序和层序遍历,统计节点个数和树的高度,查找节点,判断是否为完全二叉树,以及销毁二叉树。通过手动创建一棵二叉树,详细讲解了每个功能的实现方法和代码示例,帮助读者深入理解递归和数据结构的应用。
63 8
|
13天前
|
机器学习/深度学习 JSON 算法
二叉树遍历算法的应用场景有哪些?
【10月更文挑战第29天】二叉树遍历算法作为一种基础而重要的算法,在许多领域都有着不可或缺的应用,它为解决各种复杂的问题提供了有效的手段和思路。随着计算机科学的不断发展,二叉树遍历算法也在不断地被优化和扩展,以适应新的应用场景和需求。
24 0
|
1月前
|
存储 算法 关系型数据库
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
这篇文章主要介绍了多路查找树的基本概念,包括二叉树的局限性、多叉树的优化、B树及其变体(如2-3树、B+树、B*树)的特点和应用,旨在帮助读者理解这些数据结构在文件系统和数据库系统中的重要性和效率。
19 0
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
|
1月前
|
存储 算法 搜索推荐
数据结构与算法学习十七:顺序储存二叉树、线索化二叉树
这篇文章主要介绍了顺序存储二叉树和线索化二叉树的概念、特点、实现方式以及应用场景。
20 0
数据结构与算法学习十七:顺序储存二叉树、线索化二叉树
|
1月前
|
Java
【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(二)
【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(二)
27 1
|
1月前
|
算法 Java C语言
【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(一)
【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(一)
24 1
|
1月前
|
存储
【数据结构】二叉树链式结构——感受递归的暴力美学
【数据结构】二叉树链式结构——感受递归的暴力美学
|
1月前
|
存储 算法
【二叉树】—— 算法题
【二叉树】—— 算法题
【二叉树】—— 算法题