二叉树OJ题目合集(单值、对称、平衡、构建加遍历)

这篇具有很好参考价值的文章主要介绍了二叉树OJ题目合集(单值、对称、平衡、构建加遍历)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

前言:

一:单值二叉树

二:二叉树遍历

核心点

(1)前序

(2)中序

(3)后序

三:判断两颗树是否相同

四:判断二叉树是否对称

五:判断一颗树是否为另一颗树的子树

六:平衡二叉树

七:二叉树的构建加遍历


前言:

这一部分适合已经适用于已经掌握二叉树基础的同学(遍历,求节点数等)

不清楚的同学可以先看之前一期:

https://blog.csdn.net/2301_76269963/article/details/130231257?spm=1001.2014.3001.5502

一:单值二叉树

题目链接:https://leetcode.cn/problems/univalued-binary-tree/submissions/

题目要求:

二叉树OJ题目合集(单值、对称、平衡、构建加遍历)

基础思路:

(1)首先判断根节点值与左右子树值是否相同,如果不同就返回 false。(注意如果左右子树为空不需要进行判断)

(2)否则,递归判断其左右子树是否为单值二叉树。(空树算作单值二叉树)

(3)如果一直到叶子节点都没有出现不相同的节点值,则返回 true,表示该树为单值二叉树。

(左子树右子树同时为单值树才行)

(这个题目比较简单,不利用递归也可以实现,但是需要建立辅助栈,只要遍历所有节点依次判断,遇到不同返回false,遍历完都没有不同返回true)

代码:文章来源地址https://www.toymoban.com/news/detail-433040.html

bool isUnivalTree(struct TreeNode* root)
{
    if(root == NULL)
    {
        return true;
    }

    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);

}

图解:

二叉树OJ题目合集(单值、对称、平衡、构建加遍历)

二:二叉树遍历

核心点

(1)我们知道在函数调用时候形参只是实参的临时拷贝,如果我们直接传值调用,是没办法直接与那个变量建立联系的。

(2)如果我们想让函数不管递归深度多大都始终使用一个变量,我们应该进行传址调用

(1)前序

题目链接:https://leetcode.cn/problems/binary-tree-preorder-traversal/submissions/

题目要求:

二叉树OJ题目合集(单值、对称、平衡、构建加遍历)

思路:

①和我们之前的打印不同,这一次遍历是要把节点数据存入数组中

②先求节点数(之前一次讲过),依据节点数来开辟空间

③先存储数据,再递归走左子树,后递归走右子树,每一次存储完成都要让(*i)加1(本体加1)

④记得为(*returnSize)赋值数组元素个数,告知元素个数,别人才能进行测试

代码:

//求树的节点数
int BinaryTreeSize(struct TreeNode* root)
{
	return root == NULL ? 0 :
		BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}

void _preorderTraversal(struct TreeNode* root,int* a,int* i)
{
    if(root == NULL)
    {
        return;
    }
    //赋值
    a[*i] = root->val;
    *i+=1;
    //左子树
    _preorderTraversal(root->left,a,i);
    //右子树
    _preorderTraversal(root->right,a,i);
}

int* preorderTraversal(struct TreeNode* root, int* returnSize)
{
    //申请空间存储数据
    int size=BinaryTreeSize(root);
    int* a=(int*)malloc(sizeof(int)*size);

    //遍历存储数据(利用子函数)
    int i=0;
    _preorderTraversal(root,a,&i);

    //返回
    *returnSize = size;
    return a;
}

(2)中序

题目链接:https://leetcode.cn/problems/binary-tree-inorder-traversal/submissions/

题目要求:

二叉树OJ题目合集(单值、对称、平衡、构建加遍历)

思路:与前序基本一致,只是换了存储的顺序

代码:

//求树的节点数
int BinaryTreeSize(struct TreeNode* root)
{
	return root == NULL ? 0 :
		BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}

void _inorderTraversal(struct TreeNode* root,int* a,int* i)
{
    if(root == NULL)
    {
        return; 
    }
    
    _inorderTraversal(root->left,a,i);
    a[*i] = root->val;
    *i += 1;
    _inorderTraversal(root->right,a,i);
}

int* inorderTraversal(struct TreeNode* root, int* returnSize)
{
    //申请空间存储数据
    int size = BinaryTreeSize(root);
    int* a = (int*)malloc(sizeof(int)*size);
    
    //调用子函数存储
    int i=0;
    _inorderTraversal(root,a,&i);

    //返回
    *returnSize = size;
    return a;
}

(3)后序

题目链接:https://leetcode.cn/problems/binary-tree-postorder-traversal/submissions/

题目要求:

二叉树OJ题目合集(单值、对称、平衡、构建加遍历)

思路:与前序基本一致,只是换了存储的顺序

代码:

//求树的节点数
int BinaryTreeSize(struct TreeNode* root)
{
	return root == NULL ? 0 :
		BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}

void _postorderTraversal(struct TreeNode* root,int* a,int* i)
{
    if(root == NULL)
    {
        return;
    }
    //左子树
    _postorderTraversal(root->left,a,i);
    //右子树
    _postorderTraversal(root->right,a,i);
    //存储
    a[*i] = root->val;
    *i += 1;
}

int* postorderTraversal(struct TreeNode* root, int* returnSize)
{
    //申请空间存储
    int size = BinaryTreeSize(root);
    int* a = (int*)malloc(sizeof(int)*size);

    //调用子函数遍历存储
    int i=0;
    _postorderTraversal(root,a,&i);

    //返回
    *returnSize = size;
    return a;
}

三:判断两颗树是否相同

题目链接:https://leetcode.cn/problems/same-tree/submissions/

题目要求:

二叉树OJ题目合集(单值、对称、平衡、构建加遍历)

基础思路:

(1)先判断节点地址,如果两边都为空返回true,一边为空一边不为空返回false

(2)然后判断根部数据是否相同,不同返回false

(3)否则递归判断左子树和右子树是否相同

(4)除了根部以外,左右子树都相同两棵树才相同

代码:

bool isSameTree(struct TreeNode* p, struct TreeNode* q)
{
    if(p == NULL && p==q)
    {
        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);
}

四:判断二叉树是否对称

题目链接:https://leetcode.cn/problems/symmetric-tree/submissions/

题目要求:

二叉树OJ题目合集(单值、对称、平衡、构建加遍历)

基础思路:

(1)和前面判断两棵树是否相同很相似,这里相当于把左右子树当成1树和2树

(2)先判断节点地址,如果两边都为空返回true,一边为空一边不为空返回false

(3)先比较根部是否相同,不同返回false

(4)根部相同,递归判断1树左子树与2树右子树是否相同,1树右子树与2树左子树是否相同

(5)到叶子节点依然相同,说明这颗树轴对称

代码:

bool CheckSymmetry(struct TreeNode* left,struct TreeNode* right)
{
    //如果都为空,对称
    if(left == NULL && left == right)
    {
        return true;
    }
    //一方为空一方不为,不对称
    if(left == NULL || right == NULL)
    {
        return false;
    }

    if(left->val != right->val)
    {
        return false;
    }

    return CheckSymmetry(left->left,right->right) 
        && CheckSymmetry(left->right,right->left);
}


bool isSymmetric(struct TreeNode* root)
{
    //利用子函数判断是否对称
    return CheckSymmetry(root->left,root->right);
}

五:判断一颗树是否为另一颗树的子树

题目链接:https://leetcode.cn/problems/subtree-of-another-tree/

题目要求:

二叉树OJ题目合集(单值、对称、平衡、构建加遍历)

基础思路:

(1)大致思路就是拿母树的每一个子树依次和subRoot比较

有相同的返回true,否则返回false

(2)如果母树为空,返回false

(3)利用前面判断两棵树是否相同的函数,我们先判断母树与subRoot是否相同

(4)相同返回true,不同就递归走母树的左子树和右子树

(5)左右子树只要有一方相同就为true

代码:

//判断两颗树是否相同
bool isSameTree(struct TreeNode* p, struct TreeNode* q)
{
    if(p == NULL && p==q)
    {
        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);
}

bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot)
{
    if(root == NULL)
    {
        return false;
    }

    if(isSameTree(root,subRoot))
    {
        return true;
    }

    return isSubtree(root->left,subRoot) 
        || isSubtree(root->right,subRoot);
}

图解:

二叉树OJ题目合集(单值、对称、平衡、构建加遍历)

六:平衡二叉树

题目链接:https://leetcode.cn/problems/balanced-binary-tree/

题目要求:

二叉树OJ题目合集(单值、对称、平衡、构建加遍历)

 基础思路:

(1)节点为空返回true(空树也是平衡二叉树)

(2)利用函数(之前讲过)计算当前节点的左右子树的高度差

(3)如果高度差不超过 1,则递归判断其左右子树是否为平衡二叉树

(4)如果有任何一个节点的左右子树的高度差大于 1,则该树不是平衡二叉树

代码:

//求树高度
int BinaryTreeDepth(struct TreeNode* root)
{
	if (root == NULL)
	{
		return 0;
	}

	if (root->left == NULL && root->right == NULL)
	{
		return 1;
	}

	return fmax(BinaryTreeDepth(root->left), BinaryTreeDepth(root->right)) + 1;
}

bool isBalanced(struct TreeNode* root)
{
    if(root == NULL)
        return true;

    int leftDepth = BinaryTreeDepth(root->left);
    int rightDepth = BinaryTreeDepth(root->right);
    
    return abs(leftDepth-rightDepth)>1?false:
    isBalanced(root->left)&&isBalanced(root->right);
}

七:二叉树的构建加遍历

题目链接:https://www.nowcoder.com/practice/4b91205483694f449f94c179883c1fef?tpId=0&difficulty=&judgeStatus=&tags=&title=%E4%BA%8C%E5%8F%89%E6%A0%91&sourceUrl=&gioEnter=menu

题目要求:

二叉树OJ题目合集(单值、对称、平衡、构建加遍历)

基础思路:

(1)依据输入的字符串建树(递归)

①创建的顺序是先左子树后右子树

②为了确保递归过程中使用同一个变量,我们传下标的地址

如果字符为'#'或者'\0'(字符串走到空),节点地址赋值为空

返回创建好的树的根部节点地址

图解:

二叉树OJ题目合集(单值、对称、平衡、构建加遍历)

 二叉树OJ题目合集(单值、对称、平衡、构建加遍历)

(2)进行中序遍历(之前讲过,不赘述)

代码:

#include <stdio.h>
#include <stdlib.h>

typedef char BTDataType;

typedef struct BinaryTreeNode
{
	//存储左孩子的地址
	struct BinaryTreeNode* left;
	//存储右孩子的地址
	struct BinaryTreeNode* right;
	BTDataType data;
}BTNode;

BTNode* maketree(char*arr,int* i)
{
    if(arr[*i]=='#'||arr[*i]=='\0')
    {
        return NULL;
    }
    BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));
    newnode->data = arr[(*i)++];
     
    newnode->left = maketree(arr,i);
    //这里加1是因为字符为'#'时候直接返回了空
    //我们要走到下一个字符就要进行自加
    (*i)++;
    newnode->right = maketree(arr,i);
    return newnode;
}

//中序遍历
void InOrder(BTNode* root)
{
    if(root == NULL)
    {
        return;
    }
	
	//左树
	InOrder(root->left);
	//打印
	printf("%c ", root->data);
	//右树
	InOrder(root->right);
}

int main() 
{
    //字符串长度不超过100
    char str[100]= {0};

    //可能有多组输入   
    while(scanf("%s",str) != EOF)
    {
        //建树
        int i = 0;
        BTNode* root = maketree(str,&i);

        //遍历
        InOrder(root);
    }

    return 0;
}

到了这里,关于二叉树OJ题目合集(单值、对称、平衡、构建加遍历)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++力扣题目101--对称二叉树

    力扣题目链接(opens new window) 给定一个二叉树,检查它是否是镜像对称的。   首先想清楚,判断对称二叉树要比较的是哪两个节点,要比较的可不是左右节点! 对于二叉树是否对称,要比较的是根节点的左子树与右子树是不是相互翻转的,理解这一点就知道了 其实我们要比较

    2024年01月25日
    浏览(30)
  • 二叉树题目合集(C++)

    链接: 二叉树创建字符串 题目要求: PS :题目描述的不是特别清楚,其实就是 前序遍历 树,然后 用括号分别包含左子树和右子树遍历结果 。 基础思路: (1)不考虑括号去重 的话,其实只要 访问完当前节点后递归访问左右子树 即可,并且在访问前加左括号,访问完毕后

    2024年02月07日
    浏览(25)
  • 【数据结构】二叉树的相关操作以及OJ题目

    当一个树不是满二叉树或完全二叉树时,它是不适合使用数组存储的,它应该使用链式结构来存储。 再看二叉树基本操作前,再回顾下二叉树的概念,二叉树是: 空树 非空:根节点,根节点的左子树、根节点的右子树组成的。 从概念中可以看出,二叉树定义是递归式的,因

    2024年03月19日
    浏览(38)
  • 代码随想录额外题目| 二叉树 ●129求根到叶数字之和 ●1382二叉树变平衡●100相同的树

    #129求根到叶数字之和 回溯放进vector,然后从后往前拿,乘1 10 100 ... 很基础的回溯 my code: 随想录跟我思路差不多,但这两个是放globa的:int result; vectorint path; 最近总觉得global不安全不想放  #1382二叉树变平衡 本来遇到这种会换root的就头疼,然后看了眼随想录,是要先变成

    2024年02月14日
    浏览(22)
  • 二叉树OJ题进阶(二叉树层序遍历、根据二叉树创建字符串、判断完全二叉树、二叉树的构建及遍历、二叉树的最近公共祖先(2种))

    1.思路 用队列写: 1.从上到下,从左到右的顺序 2.非递归的方法:使用队列来完成 3.cur充当根结点,当cur不为空的时候,cur进入队列,队列不为空,cur弹出队列打印 4.如果cur的左边不为空,左边进队,右边不为空,右边进队 5.此时队列不为空,弹出队头(也就是cur的左边)打

    2024年02月05日
    浏览(31)
  • leetcode 965.单值二叉树

    🌟 leetcode链接:单值二叉树 思路: 让当前的根节点与左孩子节点与右孩子节点判断,若相等则继续向下分治,让左孩子与右孩子当作新的根节点继续判断,直到某个节点不相等。 1️⃣ 代码:

    2024年02月16日
    浏览(26)
  • Leetcode.965 单值二叉树

    Leetcode.965 单值二叉树 Rating : 1178 如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。 只有给定的树是单值二叉树时,才返回 true ;否则返回 false 。 示例 1: 输入:[1,1,1,1,1,null,1] 输出:true 示例 2: 输入:[2,2,2,5,2] 输出:false 提示: 给定树的节点数范围是

    2023年04月14日
    浏览(24)
  • 【数据结构】单值二叉树 & 相同的树 & 翻转二叉树(五)

      目录 一,单值二叉树 题目详情: 解法:父子比较法 解题思路: 思路实现: 源代码: 二,相同的树 题目详情: 解法:比较法 解题思路: 思路实现: 源代码: 三,翻转二叉树 解法:替换法 解题思路: 思路实现: 源代码: 题目详情: 如果 二叉树 每个节点都具有 相

    2024年02月07日
    浏览(30)
  • 【C语言题解】 | 965. 单值二叉树

    提示: 给定树的节点数范围是 [1, 100]。 每个节点的值都是整数,范围为 [0, 99] 。 这个题目我们通过分治思想来解题: 首先传入的是根节点 其次判断根节点是否有左子树和右子树,若存在则判断左右子树的值是否于根节点的值相同(不同则返回false,相同则继续) 若正确,

    2024年01月21日
    浏览(27)
  • 二叉树(中)+Leetcode每日一题——“数据结构与算法”“剑指Offer55-I. 二叉树的深度”“100.相同的树”“965.单值二叉树”

    各位CSDN的uu们你们好呀,今天继续数据结构与算法专栏中的二叉树,下面,让我们进入二叉树的世界吧!!! 二叉树(上)——“数据结构与算法”_认真学习的小雅兰.的博客-CSDN博客 二叉树链式结构的实现 二叉树链式结构的实现 求二叉树的高度 但是这种写法有很大的问题

    2024年02月17日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包