链式二叉树OJ问题详解

文章目录

前言

1.单值二叉树

2.相同的树

3.对称二叉树

[4. 二叉树的遍历](#4. 二叉树的遍历)

[4.1 二叉树的前序遍历](#4.1 二叉树的前序遍历)

[4.2 中序遍历](#4.2 中序遍历)

[4.3 后序遍历](#4.3 后序遍历)

[5. 翻转二叉树](#5. 翻转二叉树)

[6. 平衡二叉树](#6. 平衡二叉树)


前言

上一篇文章主要补充了链式二叉树的一些性质还有部分功能实现,那么我们可以通过所学知识来完成一些相关的OJ问题练习,每一道题目都附上了对应的题目链接,可以先自己尝试完成,再看看这篇文章的解题思路。

1.单值二叉树

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

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

我们选择创建一个辅助函数,函数参数中带上二叉树中的值,然后利用递归遍历所有节点,如果有之不相等的直接返回false。

2.相同的树

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

cpp 复制代码
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);
}

首先如果两个根节点都是NULL,那么直接返回true,那么后面只要有一个节点为空,就说明另一个根节点不为空,两个肯定是不相等的,然后再利用递归,判断左右子树的根节点是否对应相等。

3.对称二叉树

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

cpp 复制代码
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->right)&&isSameTree(p->right,q->left);
}
bool isSymmetric(struct TreeNode* root) 
{
    return isSameTree(root->left,root->right);
}

我们很容易想到,就是证明根节点的左右子树相等,那我们直接利用上一题的函数,就可以完成了。

4. 二叉树的遍历

4.1 二叉树的前序遍历

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

cpp 复制代码
int TreeSize(struct TreeNode* root)
{
    return root==NULL?0:1+TreeSize(root->left)+TreeSize(root->right);
}
void PrevOrder(struct TreeNode* root,int* arr,int* pi)
{
    if(root==NULL)
    return;
    arr[(*pi)++]=root->val;
    PrevOrder(root->left,arr,pi);
    PrevOrder(root->right,arr,pi);
}
int* preorderTraversal(struct TreeNode* root, int* returnSize)
{
    *returnSize=TreeSize(root);
    int* arr=(int*)malloc(sizeof(int)*(*returnSize));
    int i=0;//这里的i用来作为数组的下标
    PrevOrder(root,arr,&i);
    return arr;
}

在这里有两个注意点:

1.在题目的原函数中,有一个参数returnSize,这是一个指向整型变量的指针,我们需要在函数中将二叉树的节点数传给它,那么在main函数中也可以得到这个大小,这样可以方便数组的输出

2.在进行先序遍历时,我们需要一个参数i,对数组进行定位,让数据进行插入,这里使用址传递的意义是为了防止因为函数递归,在不同栈帧中,i的值不会与其他栈帧的i进行传递,那么导致i的值没有得到有效的增加,所以我们进行传址调用,对 i 解引用后再操作。

4.2中序遍历

cpp 复制代码
int TreeSize(struct TreeNode* root)
{
    return root==NULL?0:1+TreeSize(root->left)+TreeSize(root->right);
}
void InOrder(struct TreeNode* root,int* arr,int* pi)
{
    if(root==NULL)
    return;
    InOrder(root->left,arr,pi);
    arr[(*pi)++]=root->val;
    InOrder(root->right,arr,pi);
}
int* inorderTraversal(struct TreeNode* root, int* returnSize) 
{
    *returnSize=TreeSize(root);
    int* arr=(int*)malloc(sizeof(int)*(*returnSize));
    int i=0;//这里的i用来作为数组的下标
    InOrder(root,arr,&i);
    return arr;
}

这里没什么变化,就是先遍历左子树的节点,只要把顺序改变一下就行了。

4.3 后序遍历

这里不做解释了,和上面思路一致,所以只留下题目链接,代码就不留了。

5. 翻转二叉树

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

cpp 复制代码
typedef struct TreeNode Tnode;
struct TreeNode* invertTree(struct TreeNode* root) 
{
    if(root==NULL)
    return NULL;
    Tnode* cyroot=(Tnode*)malloc(sizeof(Tnode));
    cyroot->val=root->val;
    cyroot->left=invertTree(root->right);
    cyroot->right=invertTree(root->left);
    return cyroot;
}

这种问题,我的常用思路就是再创建一个新的二叉树,让它的左节点接收原树的右节点,它的右节点接收原树的左节点。因为本题并没有限制空间复杂度,所以是可行的,这种方法对很多类似的题目都是有效且易于理解的,但前提是没有空间复杂度的限制。

6. 平衡二叉树

给定一个二叉树,判断它是否是 平衡二叉树

cpp 复制代码
typedef struct TreeNode Tnode;
 int TreeHight(Tnode* root)
 {
    if(root==NULL)
    return 0;
    int ret1=TreeHight(root->left);
    int ret2=TreeHight(root->right);
    return ret1>ret2?ret1+1:ret2+1;
 }
bool isBalanced(struct TreeNode* root) 
{
    if(root==NULL)
    return true;
    int h1=TreeHight(root->left);
    int h2=TreeHight(root->right);
    if(abs(h1-h2)>1)
    return false;
    return isBalanced(root->left)&&isBalanced(root->right);
}

先写一个计算树的高度的函数,因为平衡二叉树需要该树所有节点的左右子树的高度相差不超过 1,那我们用两个整型变量来统计左右子树的高度,然后用绝对值函数来计算高度差,如果大于1,那么就不是平衡二叉树,如果是,那么还需要进行下一轮的比较。

结语

以上就是本篇文章的全部内容,那你是否已经熟练使用了函数的递归来解决二叉树的相关问题?后续我们将要开始排序的学习,感谢观看!

相关推荐
wabs6662 分钟前
关于动态规划【纯粹的0-1背包需要思考的问题】
算法·动态规划
小小编程路4 分钟前
字符串转数字时,可能会遇到哪些问题?
java·开发语言·算法
rit843249919 分钟前
MATLAB近红外光谱预处理:平滑与求导(MSV方法)
数据结构·算法·matlab
蚂蚁数据AntData24 分钟前
从ChatBI到业务记忆:重新定义数据智能的生产力边界
大数据·网络·数据库·人工智能·算法
_日拱一卒25 分钟前
LeetCode:22括号生成
算法·leetcode·职场和发展
cfm_291427 分钟前
JVM垃圾收集算法与收集器深度解析
jvm·测试工具·算法·性能优化
郝学胜_神的一滴35 分钟前
干货版《算法导论》09:让哈希表稳如泰山的终极解法
数据结构·算法
CC数学建模41 分钟前
2026年第十六届APMCM 亚太地区大学生数学建模竞赛(中文赛项)赛题C题:创业社区规划与资源配置优化问题完整思路、代码、模型、文章,全网首发高质量分享!
python·算法·数学建模
徐小夕44 分钟前
我们放弃了单Agent方案:HiCAD 3.0 用 Harness 做多Agent编排,把3D建模的准确率提升了30%
前端·算法·github
洛水水1 小时前
【力扣100题】88.多数元素
数据结构·算法·leetcode