当前位置: 首页 > article >正文

数据结构初阶-二叉树的应用

1.单值二叉树

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

题目思路:我们把根结点与左孩子和右孩子进行比较,只有左右子树都是单值二叉树的时候才为单值二叉树。但是我们需要先返回的是false,最后再返回左子树&&右子树的结果。所以代码如下:

 typedef struct TreeNode TreeNode;
bool isUnivalTree(struct TreeNode* root) 
{
    if(root==NULL)
    {
        //如果全为空的情况下,没有存储任何值也就是单值二叉树
        return true;
    }
    if(root->left && root->val != root->left->val)
    {
        //当左孩子不存在时我们仍然返回的是true
        //root->left是判断是否左子树为空的
        return false;
    }
    if(root->right && root->val !=root->right->val)
    {
        return false;
    }
    return isUnivalTree(root->left)&&isUnivalTree(root->right);
}

2.相同的树

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

题目思路:如果p、q一者为空另一者为非空,则为false,我们使用前序遍历的方法,最终返回p的左子树和q的左子树的返回值&&p的右子树和q的右子树的返回值。

typedef struct TreeNode TreeNode;
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);
}

我们主要是返回的是false,如果我们在第三个if条件下p->val==q->val return true;这样我们不确定之后的树中是否还是相同的情况,只有我们最终比较到两者都为空才行。

*3对称二叉树(扩展)

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

题目思路:由于我们发现这个给出的函数只有一个参数,但是我们需要比较的是左子树的左结点和右子树的右结点的返回值&&左子树的右结点和右子树的左结点的返回值,所以我们需要另外一个函数来判断,思路要把单值二叉树和相同的树进行整合,最终能得到以下代码:

bool panduan(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 panduan(p->left,q->right) && panduan(p->right,q->left);
    }
    return false;
 }
bool isSymmetric(struct TreeNode* root) 
{
    if(root==NULL)
    {
        return true;
    }
    return panduan(root,root);
}

4.另一棵树的子树

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

题目思路:我们把第二题的代码全部放入题目后,然后每次都调用这个函数,先递归左子树再递归右子树,并返回二者或的结果,代码如下:

typedef struct TreeNode TreeNode;
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);
}
bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot) 
{
    if(isSameTree(root,subRoot))
    {
        return true;
    }
    if(root==NULL)
    {
        return false;
    }
    return isSubtree(root->left,subRoot)||isSubtree(root->right,subRoot);
}

5.二叉树的前序遍历

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

题目思路:返回值为int*,我们需要返回数组,数组还必须手动malloc。我们需要先求出二叉树结点的个数,这个函数我们之前写过,就不需要讲解了;然后我们需要malloc结点个数的数据,最后前序遍历,最终代码如下:

typedef struct TreeNode TreeNode;
 //求二叉树结点个数
 int TreeSize(TreeNode* root)
 {
    if(root==NULL)
    {
        return 0;
    }
    return 1+TreeSize(root->left)+TreeSize(root->right);
 }
 //前序遍历
 void PreOrder(TreeNode* root,int* arr,int* pi)
 {
    if(root==NULL)
    {
        return ;
    }
    arr[(*pi)++]=root->val;
    PreOrder(root->left,arr,pi);
    PreOrder(root->right,arr,pi);
 }
int* preorderTraversal(struct TreeNode* root, int* returnSize) 
{
    //我们需要自己求出结点个数
    *returnSize=TreeSize(root);
    int* arr=(int*)malloc(sizeof(int)*(*returnSize));
    int i=0;
    //我们需要不断递增下标,所以要传址操作
    PreOrder(root,arr,&i);
    return arr;
}

拓展练习,题目链接:https://leetcode.cn/problems/binary-tree-inorder-traversal/description/

和https://leetcode.cn/problems/binary-tree-postorder-traversal/description/

6.二叉树的构建及遍历

该题目难度较难,所以有兴趣的可以去看

题目链接:https://www.nowcoder.com/practice/4b91205483694f449f94c179883c1fef

题目思路:首先我们需要根据数组来创建二叉树,之前我们是手动来创建二叉树的,所以我们没有注意这个问题,这个题目就可以锻炼我们创建二叉树的技巧。如何根据数组来创建二叉树?只要不为#我们就创建这个结点,第一个不为#的就是根结点,所以我们需要一个创建结点的函数,之前我们写过,所以很简单,然后我们用传址操作来得到每一个结点,先进行根结点的创建,再是左孩子,最后右孩子,最终代码如下:

#include <stdio.h>
//定义结点
typedef struct BinaryTreeNode
{
char data;
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
}BTNode;
//创建结点
BTNode* buyNode(char ch)
{
    BTNode* node=(BTNode*)malloc(sizeof(BTNode));
    node->data=ch;
    node->left=node->right=NULL;
    return node;
}
//创建二叉树
BTNode* createTree(char* arr,int* pi)
{
    if(arr[*pi]=='#')
    {
        (*pi)++;
        return NULL;
    }
    BTNode* root=buyNode(arr[*pi]);
    ++(*pi);
    root->left=createTree(arr,pi);
    root->right=createTree(arr,pi);
    return root;
}
//中序遍历
void InOrder(BTNode* root)
{
if(root==NULL)
{
    return;
}
InOrder(root->left);
printf("%c ",root->data);
InOrder(root->right);
}
int main() 
{
    char arr[100];
    scanf("%s",arr);
    int i=0;
    BTNode* root=createTree(arr, &i);
    InOrder(root);
    return 0;
}

 

7.总结和下节预告

这些题目难度都还行,只要虚心学习,不断在自己思考的情况下,这些题目还是很容易的。喜欢的可以一键三连哦,下节将讲解:排序1 。

 


http://www.kler.cn/a/600382.html

相关文章:

  • 1688关键字API接口解析:(实战案例)
  • Day110 若依-基础
  • mysql数据实时全量+增量迁移
  • 【论文笔记】生成对抗网络 GAN
  • 统一开放世界与开放词汇检测:YOLO-UniOW无需增量学习的高效通用开放世界目标检测框架
  • 开源视觉语言模型MiniMax-VL-01:动态分辨率+4M超长文本,性能比肩GPT-4o
  • 基础算法01——二分查找(Binary Search)
  • 蓝桥云客 数字接龙
  • Flink 流处理框架的核心特性
  • Linux第零节:Linux命令速查图表(按功能分类)
  • 使用BootStrap 3的原创的模态框组件,没法弹出!估计是原创的bug
  • C# 线程介绍
  • 调用百度api实现语音识别(python)
  • python如何获取html中附件链接,并下载保存附件
  • 珍珠港海军造船厂的“水魔法”:PcVue赋能造船心脏
  • 特征工程自动化(FeatureTools实战)
  • 前端Tailwind CSS面试题及参考答案
  • 股指期货贴水波动,影响哪些投资策略?
  • 编译原理 pl0 词法解析器 使用状态机与状态矩阵,和查找上一步得到分析
  • JAVA 单调栈习题解析