二叉树刷题(1)

二叉树题目讲解(1)

一、构建二叉树并且遍历

题目描述:编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串ABC##DE#G##F### 其中"#"表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。

示例:

输入:abc##de#g##f###

输出:c b e g d f a

(1)思路

1、首先读完题目我们需要明白题目的意思:

输入一串字符(前序遍历)根据我们的字符串构建我们的二叉树,然后再中序遍历

构建树的过程如图所示,先创建根节点,然后遍历左子树,然后右子树,所以建树的过程是递归的过程。

2、我们该如何实现呢?

(1)首先我们先创建一个字符数组将我们的字符串放入,因为是数组所以我们需要一个下标来访问我们的数组,但由于我们的建树过程是递归的,所以我们的下标需要在main函数里定义。

(2)然后就进入我们的建树函数里,结束条件是什么呢?大家想如果遇到空是不是就要返回到上一级,所以结束条件就是如果遇到'#'就返回,并且由于这是在数组里,我们需要下标++。

(3)然后我们就可以开始我们的建根,如果当前数组元素不为"#"就创建根节点,

那根节点的左子树怎么办?那我们就递归,根的left就直接递归,右孩子同理。

这里体现了我么的分置的思想。

(2)代码

c 复制代码
#include <stdio.h>
#include<string.h>

typedef struct treenode
{
    char val;
    struct treenode*left;
    struct treenode*right;
}TNode;//定义树的节点

TNode*createtree(char*arr,int*i)
{
    if(arr[*i]=='#')//如果当前节点为空就返回上一级
    {
        (*i)++;
        return NULL;
    }
    TNode*root=(TNode*)malloc(sizeof(TNode));//创建根节点
    root->val=arr[(*i)++];
    root->left=createtree(arr,i);//递归根的左子树
    root->right=createtree(arr,i);//递归根的右子树
    return root;//最后返回根节点即可
}
void midtravel(TNode*root)//中序遍历
{
    if(root==NULL)
        return;
    midtravel(root->left);
    printf("%c ",root->val);
    midtravel(root->right);
}
int main() {
    char arr[100];
    gets(arr);//得到我们的字符串
    int i=0;
    TNode*root=createtree(arr,&i);//为什么这里用i的地址
    //这是因为如果值传递在递归里我们加不上去
    midtravel(root);
    return 0;
}

二、对称二叉树

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

示例:

1、思路

这道题我们的思路是什么呢?

(1)首先我们需要明白什么样的树才是我们的对称二叉树,是不是左子树的左子树等于右子树的右子树,右子树的左子树等于左子树的右子树,那这里跟我们的根节点有关系吗?所以如果我们的根为空就返回true,如果不为空就进入判断左子树与右子树是否是镜像的。

(2)在函数里我们怎么实现呢?首先我们需要判断左子树与右子树是否都为空,如果都为空,那我们的树只有一个根节点,那就返回true,然后我们需要判断是否有一个子树为空,如果有的话那我们的树就不是镜像二叉树。

(3)上面完成以后我们的树就一定有两颗子树,但我们还没有比较它们的值是否相等,如果不相等就返回false,然后再比较左子树的左子树与右子树的右子树是否相等,再比较右子树的左子树是否与左子树的右子树相等即可

2、代码

c 复制代码
bool _isSymmetric(struct TreeNode*p,struct TreeNode*q)
 {
    if(p==NULL&&q==NULL)//如果左右子树都为空
        return true;
    if(p==NULL||q==NULL)//第一个if排除了两者都为空的情况,这里判断是否有一个不为空
        return false;
    if(p->val!=q->val)
        return false;
    return _isSymmetric(p->left,q->right)&&_isSymmetric(p->right,q->left);
 }
bool isSymmetric(struct TreeNode* root)
 {
    if(root==NULL)//如果根节点为空,就是空树
        return true;
    return _isSymmetric(root->left,root->right);
}

三、相同的树

题目描述

给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。

如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

示例:

1、思路

在完成了上面的对称二叉树后这道题就简单很多嘛!

首先我们需要判断两棵树是否都为空以及一个不为空一个为空这两种情况,在判断完上面以后我们的两棵树一定都有根节点,然后我们判断根的值是否相等,最后遍历我们的左树的左树与右数的左树,左树的右树与右树的右树即可。

2、代码

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

四、单值二叉树

题目描述:

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

只有给定的树是单值二叉树时,才返回 true;否则返回 false。

示例:

1、思路

这道题我们首先需要判断树是否为空,如果为空则返回true,如果不是空树,我们就比较左子树的值与根节点的值是否相等,再比较右子树的值与根节点是否相等,如果不相等则返回false,最后递归我们的左子树与右子树。

这里也走的我们的分治的思想。

2、代码

c 复制代码
bool isUnivalTree(struct TreeNode* root) {
    if(root==NULL)
        return true;
    if(root->left&&root->val!=root->left->val)
        return false;
    if(root->right&&root->val!=root->right->val)
        return false;
    return isUnivalTree(root->left)&&isUnivalTree(root->right);
}

五、另一棵树的子树

题目描述:

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

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

示例:

1、思路

这道题其实思路非常的简单,我们不是求是否为子树嘛,那我们可以走一个前序遍历,比较每一个节点作为树与右边的所求的子树,再走一个issametree即可。

2、代码

c 复制代码
bool issametrue(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 issametrue(p->left,q->left)&&issametrue(p->right,q->right);
}

bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot){
    if(root==NULL&&subRoot==NULL)
        return true;
    if(root==NULL||subRoot==NULL)
        return false;
    if(issametrue(root,subRoot))
        return true;
    return isSubtree(root->left,subRoot)||isSubtree(root->right,subRoot);
}
相关推荐
Chase-Hart1 小时前
【每日一题】LeetCode 7.整数反转(数学)
java·数据结构·算法·leetcode·eclipse
四角小裤儿儿1 小时前
Java数据结构(十一)——归并排序、计数排序
java·数据结构·排序算法
朱皮皮呀2 小时前
排序算法-归并排序
数据结构·算法·排序算法·归并排序
jyan_敬言2 小时前
虚拟机centos_7 配置教程(镜像源、配置centos、静态ip地址、Finalshell远程操控使用)
linux·运维·服务器·c语言·数据结构·tcp/ip·centos
UrSpecial2 小时前
【数据结构取经之路】图解AVL树
数据结构
QXH2000002 小时前
数据结构—顺序表
数据结构
fhvyxyci5 小时前
【数据结构初阶】顺序结构二叉树(堆)接口实现超详解
c语言·数据结构
禁默8 小时前
list从0到1的突破
数据结构·c++·list
laocooon5238578868 小时前
一个线性筛的多功能组合:筛法求质数+约数个数+约数和
数据结构·c++·算法
银氨溶液10 小时前
MySQL底层为什么选择用B+树作为索引
数据结构·数据库·b树·mysql·面试·b+树