链式二叉树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,那么就不是平衡二叉树,如果是,那么还需要进行下一轮的比较。

结语

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

相关推荐
2401_844221321 小时前
使用PictureBox实现图片缩放与显示的深入探讨
jvm·数据库·python·算法
Java面试题总结2 小时前
Go图像处理基础: image包深度指南
图像处理·算法·golang
C羊驼2 小时前
C 语言:哥德巴赫猜想
c语言·开发语言·人工智能·经验分享·笔记·算法·课程设计
田梓燊2 小时前
算法题学习题单
学习·算法
Sunsets_Red2 小时前
乘法逆元的 exgcd 求法
c++·学习·数学·算法·c#·密码学·信息学竞赛
阿Y加油吧2 小时前
力扣打卡——接雨水、无重复字符的最长子串
算法·leetcode·职场和发展
handler012 小时前
算法:字符串哈希
c语言·数据结构·c++·笔记·算法·哈希算法·散列表
琪蘤2 小时前
点胶换阀高度标定计算说明
算法