【数据结构和算法】--- 二叉树(5)--二叉树OJ题

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: 【数据结构和算法】--- 二叉树(5)--二叉树OJ题

一、二叉树OJ题

1.1 单值二叉树

题目描述: 如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。只有给定的树是单值二叉树时,才返回true;否则返回 false

做题链接: 965. 单值二叉树

解题思路:

我们可以利用递归分治的思想,将此问题分解为:根节点和左孩子的值是否相等(root->left->val != root->val),根节点和右孩子的值是否相等(root->right->val != root->val),左子树判断,右子树判断。

且在每次值相等判断之前都要 先确定,当前根节点是否为空(root == NULL),若为空就直接返回true表示相等。因为我们会不能确定当前节点的左右孩子是否为空节点,所以每次在比较当前节点和孩子节点的值的时候,都要先判断(root->left != NULL或root->right != NULL),以确保不会对空节点解引用。如果值不相等便返回false。

最后一步便是继续递归当前节点的左子树(root->left)和右子树(root->right),那么如果左子树或右子树都为相同的值那么便返回true,如果有一个不相同便会返回false。既然这样,那么我们便可使用&&将递归左和右子树的函数连接起来(isUnivalTree(root->left) && isUnivalTree(root->right))。并将此结果作为返回值,只有同为true,才会真正的返回true。


解题代码:

bool isUnivalTree(struct TreeNode* root) {
    if(root == NULL)
        return true;
    //左右孩子和当前节点的值的判断
    //1、先判孩子不为空; 2、再判孩子和根的值。
    if(root-> left != NULL && root->left->val != root->val)
        return false;
    if(root-> right != NULL && root->right->val != root->val)
        return false;
    //左右子树的递归判断
    return isUnivalTree(root->left) && isUnivalTree(root->right);
}

代码图解:

1.2 检查两颗树是否相同

题目描述: 给你两棵二叉树的根节点pq,编写一个函数来检验这两棵树是否相同。如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

做题链接: 100. 相同的树

解题思路:

同样可以利用递归分治的思想:两棵二叉树根节点是否相同,左子树是否相同,右子树是否相同。 首先判断两棵二叉树的根节点是否为空,若都为空(p == NULL && q == NULL)则定为相等,返回true。但是如果只有一个节点是空节点的话,那么便要返回false,此处可以使用p == NULL || q == NULL来判断。

相信有人会问,这样判断的话如果两个都是空节点的话,那不就返回false了吗?当然不会,如果能从第一个判断出来,就说明不会出现都为空的情况,那么进入此if语句的条件就只有两个节点中的一个为空!

判断完空节点的情况,我们便可判断这两个节点的值是否相同,若不同则返回false。最后再递归两棵二叉树的左右子树,若两函数都为true,则最终返回true。


解题代码:

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 false;
    return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}

代码图解:


1.3 对称二叉树

题目描述: 给你一个二叉树的根节点 root , 检查它是否轴对称。

做题链接: 101. 对称二叉树

解题思路:

看上面这个二叉树,如果我们将它分为,根节点,左子树,右子树。如果将左子树和右子树拆分开,那么判断对称二叉树,便可转化为检查两颗树是否相同!!

那么便可在1.2的基础上修改一下代码即可,即二叉树p的左子树和二叉树q的右子树是否相同,(isSameTree(p->left, q->right) && isSameTree(p->right, q->left)),因为两棵二叉树是镜像的关系。

解题代码:

//检查两颗树是否相同
bool isSameTree(struct TreeNode* p, struct TreeNode* q)
{
    if(!p && !q)
        return true;
    if(!p || !q)
        return false;
    if(q->val != p->val)
        return false;
    return isSameTree(p->left, q->right) && isSameTree(p->right, q->left);
}
//分出左右子树
bool isSymmetric(struct TreeNode* root) {
    return isSameTree(root->left, root->right);
}

1.4 另一颗树的子树

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

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

做题链接: 572. 另一棵树的子树

解题思路:

此题思路任然与1.2检查两颗树是否相同,相似。若在root中寻找subRoot,那么便可以先判断当前二叉树root与sunRoot是否相似,若相似则返回true;不相似则继续递归root的左子树和右子树。 还需要注意的是,此处判断左右子树的函数使用||相连,因为只要左右子树中一个有subRoot即可。

解题代码:

bool isSubtree(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 false;
    return isSubtree(root->left,subRoot) || isSubtree(root->right,subRoot);
}

1.5 平衡二叉树

做题链接: 110. 平衡二叉树

题目描述: 给定一个二叉树,判断它是否是高度平衡的二叉树。本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。

解题思路:

既然要判断左右子树的高度差,那么就要写出求二叉树的高度的函数。此函数实现思想:遇到空节点便返回0,然后递归左右子树,每递归一层便加一,返回左子树高度和右子树高度中的较大者,利用fmax()函数求较大值,具体思想还请参考图解:

基于上述求二叉树最大高度的函数BinaryTreeHeight,那么便可利用递归分治的思想:根节点下左右子树的高度差,根节点左孩子作为二叉树第一层的左右子树的高度差,根节点右孩子作为二叉树第一层的左右子树的高度差。

遇到空节点便返回true,先利用BinaryTreeHeight函数求出左子树(leftHeight)和右子树(rightHeight)的最大高度,然后比较高度差(abs(leftHeight - rightHeight) > 1),若大于一则返回false,最后再递归左右子树。

解题代码:

//求当前节点下的左子树和右子树高度,并返回较大值
int BinaryTreeHeight(struct TreeNode* root)
{
   if(root == NULL)
       return 0;
   int leftHeight = BinaryTreeHeight(root->left) + 1;
   int rightHeight = BinaryTreeHeight(root->right) + 1;
   return fmax(leftHeight, rightHeight);
}
//主函数
bool isBalanced(struct TreeNode* root) 
{
    if(root == NULL)
        return true;
    //左 右子树高度
    int leftHeight = BinaryTreeHeight(root->left);
    int rightHeight = BinaryTreeHeight(root->right);
    //差值判断
    if(abs(leftHeight - rightHeight) > 1)
        return false;
    //递归左右子树
    return isBalanced(root->left) && isBalanced(root->right);
}

二、概念选择题

  1. 在一颗完全二叉树中,某一个结点没有其左孩子,则该结点一定(B
    A.是根结点
    B.是叶结点
    C.是分支结点
    D.在倒数第二层

解析: 完全二叉树中如果一个节点没有左孩子,则一定没有右孩子,必定为一个叶子节点,最后一层一定为叶子节点,但是倒数第二层也可能存在叶子节点。

  1. 有n个元素的完全二叉树的深度是(D
    A.nlogn
    B.nlogn+1
    C.logn
    D.logn+1
  2. 在一颗度为3的树中,度为3的结点有2个,度为2的结点有1个,度为1的结点有2个,则叶子结点有(B)个。

解析: 设度为i的节点个数为ni。 该树总共有n个节点,则n=n0+n1+n2+n3。有n个节点的树的总边数为n-1条。根据度的定义,总边数与度之间的关系为:n-1=0*n0+1*n1+2*n2+3*n3。联立两个方程求解,可以得到n0 = n2 + 2n3 + 1, n0=6。

  1. 下列关于二叉树的叙述错误的是( A
    A.二叉树指的是深度为 2 的树
    B.一个 n 个结点的二叉树将拥有 n-1 条边
    C.一颗深度为 h 的满二叉树拥有 2^h-1 个结点(根结点深度为1)
    D.二叉树有二叉链和三叉链两种表示方式

解析: A错误: 二叉树指最大孩子个数为2,即树的度为二的树。深度描述的为树的层数。

B正确:对于任意的树都满足:边的条数比节点个数少1,因为每个节点都有双亲,但是根节点没有

C正确:正确,参加二叉树性质

D正确:二叉链一般指孩子表示法,三叉连指孩子双亲表示法,这两种方式是二叉树最常见的表示方式,虽然还有孩子兄弟表示法,该中表示方式本质也是二叉链。

  1. 设根结点的深度为1,则一个拥有n个结点的二叉树的深度一定在(A)区间内
    A.[log(n + 1),n]
    B.[logn,n]
    C.[log(n + 1),n - 1]
    D.[log(n + 1),n + 1]

解析: 最大深度: 即每次只有一个节点,次数二叉树的高度为n,为最高的高度。最小深度: 此树为完全二叉树, 如果是完全二叉树。根据二叉树性质,完全二叉树的高低为 h = log(n+1)向上取整。

目录
相关文章
|
16天前
|
算法 数据处理 C语言
C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合
本文深入解析了C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合,旨在帮助读者掌握这一高效的数据处理方法。
26 1
|
19天前
|
机器学习/深度学习 算法 数据挖掘
K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构
K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构。本文介绍了K-means算法的基本原理,包括初始化、数据点分配与簇中心更新等步骤,以及如何在Python中实现该算法,最后讨论了其优缺点及应用场景。
63 4
|
17天前
|
存储 算法 搜索推荐
Python 中数据结构和算法的关系
数据结构是算法的载体,算法是对数据结构的操作和运用。它们共同构成了计算机程序的核心,对于提高程序的质量和性能具有至关重要的作用
|
17天前
|
数据采集 存储 算法
Python 中的数据结构和算法优化策略
Python中的数据结构和算法如何进行优化?
|
25天前
|
算法
数据结构之路由表查找算法(深度优先搜索和宽度优先搜索)
在网络通信中,路由表用于指导数据包的传输路径。本文介绍了两种常用的路由表查找算法——深度优先算法(DFS)和宽度优先算法(BFS)。DFS使用栈实现,适合路径问题;BFS使用队列,保证找到最短路径。两者均能有效查找路由信息,但适用场景不同,需根据具体需求选择。文中还提供了这两种算法的核心代码及测试结果,验证了算法的有效性。
86 23
|
25天前
|
算法
数据结构之蜜蜂算法
蜜蜂算法是一种受蜜蜂觅食行为启发的优化算法,通过模拟蜜蜂的群体智能来解决优化问题。本文介绍了蜜蜂算法的基本原理、数据结构设计、核心代码实现及算法优缺点。算法通过迭代更新蜜蜂位置,逐步优化适应度,最终找到问题的最优解。代码实现了单链表结构,用于管理蜜蜂节点,并通过适应度计算、节点移动等操作实现算法的核心功能。蜜蜂算法具有全局寻优能力强、参数设置简单等优点,但也存在对初始化参数敏感、计算复杂度高等缺点。
57 20
|
16天前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
42 1
|
24天前
|
机器学习/深度学习 存储 算法
数据结构实验之二叉树实验基础
本实验旨在掌握二叉树的基本特性和遍历算法,包括先序、中序、后序的递归与非递归遍历方法。通过编程实践,加深对二叉树结构的理解,学习如何计算二叉树的深度、叶子节点数等属性。实验内容涉及创建二叉树、实现各种遍历算法及求解特定节点数量。
74 4
|
25天前
|
机器学习/深度学习 算法 C++
数据结构之鲸鱼算法
鲸鱼算法(Whale Optimization Algorithm,WOA)是由伊朗研究员Seyedali Mirjalili于2016年提出的一种基于群体智能的全局优化算法,灵感源自鲸鱼捕食时的群体协作行为。该算法通过模拟鲸鱼的围捕猎物和喷出气泡网的行为,结合全局搜索和局部搜索策略,有效解决了复杂问题的优化需求。其应用广泛,涵盖函数优化、机器学习、图像处理等领域。鲸鱼算法以其简单直观的特点,成为初学者友好型的优化工具,但同时也存在参数敏感、可能陷入局部最优等问题。提供的C++代码示例展示了算法的基本实现和运行过程。
43 0
|
1月前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
159 9