【二叉树】—— 算法题

简介: 【二叉树】—— 算法题

一、单值二叉树

       题目要求:判断二叉树是不是单值二叉树(就是所以节点的值都相等)。

思路:

       利用二叉树的递归思想,判断每一个节点值与其左右子节点的值是否相等,如果遇到空节点,就返回true(说明每一个节点值都相等);如果遇到节点的值与其左右节点值不相等就返回false;如果该节点的值与其左右子节点的值都相等,就接着递归该节点的左右子树。

代码如下:

bool isUnivalTree(struct TreeNode* root) {
    if (root == NULL) {
        return true;
    }
    if (root->left && root->left->val != root->val) {
        return false;
    }
    if (root->right && root->right->val != root->val) {
        return false;
    }
 
    return isUnivalTree(root->left) && isUnivalTree(root->right);
}

二、相同的树对称二叉树另一颗树的子树

       2.1、相同的树

       判断两个二叉树是否相等

思路:

       同时遍历两个二叉树,如果遍历到两个二叉树节点同时为空,就说明这两个二叉树相同;如果其中一个为空而另一个不为空,就说明两个二叉树不相同;如果遍历过程中,遇到两个二叉树节点的值不相等,则两个二叉树不相同。

简单分析一下:

       同时遍历这两个二叉树

       两个二叉树节点都不为空且值相等,继续遍历其左子树

       两个二叉树节点都不为空且值相等,继续遍历其左子树

       两个二叉树节点都为空,返回true

       先遍历二叉树是2节点的右节点,也为空,这里直接跳过了。

       这里回退到1这个节点,接下来遍历1的右子树

       遍历到节点都不为空,且值相等,继续遍历 (这因为3的左右节点都为空,就一步带过)

       遍历结束,没有遇到一个节点为空一个节点不为空或者值不相等的情况,就返回true。

代码如下:

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

       2.2、对称二叉树

       

       判断二叉树是否是对称二叉树,这里还是实现与上题相同的树类似的思路。

思路:

       利用相同的树的方法,判断二叉树根节点的左右子树是否对称(判断对称直接判断一个节点的左子树和另一个节点的右子树是否相等即可)。

代码如下:

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

       2.3、另一颗树的子树

       判断一个树是否是另一个树的子树

思路:

       还是利用相同二叉树的方法,判断二叉树及其左右子树中是否存在与另一棵树相同的树。

代码如下:

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

三、二叉树的遍历(前序中序后序

       本题要求,前序遍历二叉树,并且返回前序遍历的结果(以数组方式返回),并且还用通过指向修改数据个数。

思路:

       这里首先求二叉树的节点个数;然后动态申请内存来存储数据并且用来最后返回数组首元素地址;最后就是将数据存储到数组当中了,使用前序遍历。

代码如下:

typedef struct TreeNode TreeNode;
int TreeSize(TreeNode* root) {
    if (root == NULL) {
        return 0;
    }
    return TreeSize(root->left) + TreeSize(root->right) + 1;
}
void _preorderTraversal(TreeNode* root,int* arr,int* pi)
{
    if(root==NULL)
    {
        return ;
    }
    arr[(*pi)++]=root->val;
    _preorderTraversal(root->left,arr,pi);
    _preorderTraversal(root->right,arr,pi);
}
int* preorderTraversal(struct TreeNode* root, int* returnSize) {
 
    // 求出二叉树的节点个数
    *returnSize =TreeSize(root);
    // 动态申请空间大小
    int* returnArr=(int*)malloc(sizeof(int)*(*returnSize));
    // 前序遍历
    int i=0;
    _preorderTraversal(root,returnArr,&i);
    return returnArr;
}

中序和后序遍历与其思路一样这里直接看代码。

中序遍历

 typedef struct TreeNode TreeNode;
int TreeSize(TreeNode* root) {
    if (root == NULL) {
        return 0;
    }
    return TreeSize(root->left) + TreeSize(root->right) + 1;
}
void _inorderTraversal(TreeNode* root,int* arr,int* pi)
{
    if(root==NULL)
    {
        return ;
    }
    _inorderTraversal(root->left,arr,pi);
    arr[(*pi)++]=root->val;
    _inorderTraversal(root->right,arr,pi);
}
int* inorderTraversal(struct TreeNode* root, int* returnSize) {
 
    // 求出二叉树的节点个数
    *returnSize =TreeSize(root);
    // 动态申请空间大小
    int* returnArr=(int*)malloc(sizeof(int)*(*returnSize));
    // 中序遍历
    int i=0;
    _inorderTraversal(root,returnArr,&i);
    return returnArr;
}

后序遍历

  typedef struct TreeNode TreeNode;
int TreeSize(TreeNode* root) {
    if (root == NULL) {
        return 0;
    }
    return TreeSize(root->left) + TreeSize(root->right) + 1;
}
void _postorderTraversal(TreeNode* root,int* arr,int* pi)
{
    if(root==NULL)
    {
        return ;
    }
    _postorderTraversal(root->left,arr,pi);
    _postorderTraversal(root->right,arr,pi);
    arr[(*pi)++]=root->val;
}
int* postorderTraversal(struct TreeNode* root, int* returnSize) {
 
    // 求出二叉树的节点个数
    *returnSize =TreeSize(root);
    // 动态申请空间大小
    int* returnArr=(int*)malloc(sizeof(int)*(*returnSize));
    // 中序遍历
    int i=0;
    _postorderTraversal(root,returnArr,&i);
    return returnArr;
}

四、二叉树的构建和遍历

       创建二叉树,并且中序遍历。

因为这里题目说先序遍历字符串(我们根据这个来构建二叉树),本题要求写全部代码。

思路:

       先创建字符数组,根据输入的字符串进行创建二叉树,创建完成以后再进行中序遍历输出即可。

代码如下:

#include <stdio.h>
#include<stdlib.h>
typedef struct BinaryTreeNode
{
    char str;
    struct BinaryTreeNode* left;
    struct BinaryTreeNode* right;
}BTNode;
 
BTNode* BuyNode(char x)
{
    BTNode* newnode=(BTNode* )malloc(sizeof(BTNode));
    newnode->str=x;
    newnode->left=newnode->right=NULL;
    return newnode;
}
BTNode* CreatTree(char* str,int* pi)
{
    if(str[*pi]=='#')
    {
        (*pi)++;
        return NULL;
    }
    BTNode* root=BuyNode(str[(*pi)++]);
    root->left=CreatTree(str,pi);
    root->right=CreatTree(str,pi);
    return root;
}
//中序遍历
void InOrder(BTNode* root)
{
    if(root==NULL)
    {
        return;
    }
    InOrder(root->left);
    printf("%c ",root->str);
    InOrder(root->right);
}
int main() {
    char str[100];
    scanf("%s",str);
    //根据字符创建二叉树
    int i=0;
    BTNode* root=CreatTree(str, &i);
    InOrder(root);
    return 0;
}

感谢各位大佬支持并指出问题,

                       如果本篇内容对你有帮助,可以一键三连支持以下,感谢支持!!!

相关文章
|
4月前
|
存储 算法 Java
Java中,树与图的算法涉及二叉树的前序、中序、后序遍历以及DFS和BFS搜索。
【6月更文挑战第21天】Java中,树与图的算法涉及二叉树的前序、中序、后序遍历以及DFS和BFS搜索。二叉树遍历通过访问根、左、右子节点实现。DFS采用递归遍历图的节点,而BFS利用队列按层次访问。以下是简化的代码片段:[Java代码略]
40 4
|
2天前
|
存储 算法 关系型数据库
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
这篇文章主要介绍了多路查找树的基本概念,包括二叉树的局限性、多叉树的优化、B树及其变体(如2-3树、B+树、B*树)的特点和应用,旨在帮助读者理解这些数据结构在文件系统和数据库系统中的重要性和效率。
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
|
2天前
|
存储 算法 搜索推荐
数据结构与算法学习十七:顺序储存二叉树、线索化二叉树
这篇文章主要介绍了顺序存储二叉树和线索化二叉树的概念、特点、实现方式以及应用场景。
数据结构与算法学习十七:顺序储存二叉树、线索化二叉树
|
4月前
|
存储 算法
【数据结构和算法】--- 二叉树(4)--二叉树链式结构的实现(2)
【数据结构和算法】--- 二叉树(4)--二叉树链式结构的实现(2)
35 0
|
4月前
|
存储 算法 Linux
【数据结构和算法】---二叉树(1)--树概念及结构
【数据结构和算法】---二叉树(1)--树概念及结构
44 0
|
2天前
|
存储 算法
数据结构与算法学习十六:树的知识、二叉树、二叉树的遍历(前序、中序、后序、层次)、二叉树的查找(前序、中序、后序、层次)、二叉树的删除
这篇文章主要介绍了树和二叉树的基础知识,包括树的存储方式、二叉树的定义、遍历方法(前序、中序、后序、层次遍历),以及二叉树的查找和删除操作。
|
2月前
|
算法
【初阶数据结构篇】二叉树算法题
二叉树是否对称,即左右子树是否对称.
20 0
|
2月前
|
存储 算法 Java
LeetCode经典算法题:二叉树遍历(递归遍历+迭代遍历+层序遍历)以及线索二叉树java详解
LeetCode经典算法题:二叉树遍历(递归遍历+迭代遍历+层序遍历)以及线索二叉树java详解
67 0
|
2月前
|
算法 Java
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
36 0
|
3月前
|
算法
刷算法Leetcode---9(二叉树篇Ⅲ)
刷算法Leetcode---9(二叉树篇Ⅲ)
30 3