二叉树的OJ题(练习)

 这篇博客的主要内容就是做几道题加强一下。

   一共七道题,力扣6道,牛客网1道。

        话不多说了直接上题。

        一 单值二叉树

        https://leetcode.cn/problems/univalued-binary-tree/description/

        大家可以先思考一下,这个题的思路就是我们要把所有的点比一下,找出不符合要求的,直接返回false,我们只需要拿左右孩子和双亲比就可以了,如果相等了,左右孩子自然也就相等。

                就拿这个图来写一下吧,开始在根节点,不为空,往下走,左右均不为空,然后和左右孩子比较,相等,然后去到左边的1那里,然后再比较发现相等,再去左边的1,返现均为空,然后返回true,此时的函数栈帧中两个均为true,所以返回true,其他的也同理。

二.相同的树

        题目描述:

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

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

首先我们来分析一下他都有哪些情况,一种就是两个都是空树,此时要返回true,一个空一个非空,要返回false,两个不相等的要返回false。

        所以就有了这个,第一个全为空,第二个其中一个为空,不可能同时为空,同时的话就进入第一个判断中了,当进行第三个判断的时候,此时均不为空了。

        然后开始递归了,每次递归都比较一下。

三 另一棵树的子树

        题目描述:

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

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

        这个要用到上一题的判断两棵树的方法,如果都是空,那就返回false,接下来开始递归,开始进入第二个判断,进入上面那个函数中,发现4和3不相同,所以直接返回false,递归左边,不为空,再判断是否相同,发现4和4相同,都递归左,发现1和1相同,空和空相同,就可以返回true了。

四 前序遍历

题目描述:给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

        好好看看。

五.中序遍历

        

六 后序遍历

        

和上面的一样,只是改变了一下顺序。


七 二叉树的遍历

        题目描述:

        

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

输入描述:

输入包括1行字符串,长度不超过100。

输出描述:

可能有多组测试数据,对于每组数据, 输出将输入字符串建立二叉树后中序遍历的序列,每个字符后面都有一个空格。 每个输出结果占一行。

示例1

输入:

abc##de#g##f###

复制输出:

c b e g d f a

        这是让我们自己设计一个算法来实现这个功能,首先它要求我们用数组来实现一个二叉树的创建。

#include <stdio.h>

#include <stdlib.h>

// 二叉树节点结构体定义

typedef struct TreeNode {

    char data;

    struct TreeNode* lchild;

    struct TreeNode* rchild;

} TreeNode;

TreeNode* buyNode(char ch){

    TreeNode* newnode=(TreeNode*)malloc(sizeof(TreeNode));

    newnode->data=ch;

    newnode->lchild=NULL;

    newnode->rchild=NULL;

    return newnode;

}

TreeNode* createTree(char* data,int* pi){

    char ch=data[*pi];

    (*pi)++;

    if(ch=='#'){

        return NULL;

    }

    TreeNode* newnode=buyNode(ch);

    newnode->lchild=createTree(data, pi);

    newnode->rchild=createTree(data, pi);

    return newnode;

}

void Inperor(TreeNode* ps){

    if(ps==NULL){

        return;

    }

    Inperor(ps->lchild);

    printf("%c ",ps->data);

    Inperor(ps->rchild);

}

int main(){

    char arr[100];

    scanf("%s",arr);

    int pi=0;

    TreeNode* newnode=createTree(arr, &pi);

    Inperor(newnode);

}

        我们大概能写出这样的一个代码,通过buyNode来实现节点的创建,通过createTree函数来实现树的创建,我们现在来实现一下树的创建过程。我们用题目中的那个例子。

        首先只是创建了三个节点出来,并没有形成树,但是在出现#之后,返回了NULL,此时就是这样了。

        因为c的左右孩子均为空,所以c的函数栈帧中的lchild和rchild都是NULL,此时把c就返回给了b的lchild中,此时就连起来了一条线。

        最后会得到这样的一棵树,接着上面来讲,此时该递归d的右孩子了,创建了一个d,再递归d的左孩子,创建了一个e这个节点,然后为#,说明e的左孩子为空,递归e的右孩子,就创建了一个g,g的左右孩子均为空,此时返回了两个NULL,此时g的函数栈帧结束把newnode也就是g返回到了e的newnode->rchild中了,此时e和g就连接起来了,此时e的函数栈帧结束,返回e到d的左孩子,就连接起来了,此时递归d的右孩子,然后创建了f,f的左右孩子为空,返回两个NULL,此时函数结束,把f返回到d的右孩子中,然后d这个函数栈帧结束,把d返回到b的右孩子中,此时b的函数栈帧结束,返回到了a的左孩子中,此时最后一个#代表了a的右孩子为空,就创建出了这样的一个二叉树,然后就是遍历了。

        


        八. 结束语

          感谢大家的查看,希望可以帮助到大家,做的不是太好还请见谅,其中有什么不懂的可以留言询问,我都会一一回答。  感谢大家的一键三连。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值