【二叉树算法题】

二叉树算法题

单值二叉树

https://leetcode.cn/problems/univalued-binary-tree/description/

c 复制代码
 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){
    if(root == NULL)
        return true;
    int val = root->val;
    return _isUnivalTree(root, val);
}

要判断是否为单值二叉树,大致的思路为判断每一个结点与其子节点或父节点的值是否相同,直到遍历完成返回ture或者找到与其他结点的值不同时返回flase,这样做可以充分利用递归来实现,同时也运用了二叉树遍历的思想。

相同二叉树

https://leetcode.cn/problems/same-tree/description/

c 复制代码
bool isSameTree(struct TreeNode* p, struct TreeNode* q){
    if(p == NULL && q != NULL)
        return false;
    if(p != NULL && q == NULL)
        return false;
    if(p == NULL && q == NULL)
        return true;
    
    if(p->val == q->val)
        return  isSameTree(p->left, q->left)
                && isSameTree(p->right, q->right);
    else
        return false;
}

判断两颗二叉树是否相同,不仅需要我们判断每一个结点的值是否相同,还要判断其长度是否相等,我们可以将其分为左子树与右子树来分别遍历判断,一旦左子树或者右子树有一个不相等,就像该返回flase所以与单值二叉树的思路大差不差,只不过将比较的值改为两棵树的同一结点位置。同时还需要比较长度是否相等。

另一棵树的子树

https://leetcode.cn/problems/subtree-of-another-tree/description/

c 复制代码
bool isSameTree(struct TreeNode* p, struct TreeNode* q){
   if(p == NULL && q != NULL)
       return false;
   if(p != NULL && q == NULL)
       return false;
   if(p == NULL && q == NULL)
       return true;
   
   if(p->val == q->val)
       return  isSameTree(p->left, q->left)
               && isSameTree(p->right, q->right);
   else
       return false;
}

bool isSubtree(struct TreeNode* s, struct TreeNode* t){     
   if(s == NULL)
       return false;
   //根相同,判断当前这个树是否和t相同
   if(isSameTree(s, t))
       return true;
   return isSubtree(s->left, t)
           || isSubtree(s->right, t);
}

意思为一个二叉树是否与另一个的二叉树中的一个子树相等,相等返回ture,不相等返回flase,所以仍然拆为左右子树来分别判断是否相等,所以我们先利用先前实现过的判断是否相同二叉树的代码,在原基础上进项修改,先判断是否相同两个树,在判断两个数的子树是否相同,一直递归直到遍历完成。

二叉树遍历

前序遍历: https://leetcode.cn/problems/binary-tree-preorder-traversal/description/

c 复制代码
int BSize(struct TreeNode* root)
{
    if(root == NULL)
        return 0;
    return BSize(root->left)
        + BSize(root->right) + 1;
}

void _preOrder(struct TreeNode* root, int* a, int* pi)
{
    if(root)
    {
        //前序遍历,保存当前节点的值
        a[*pi] = root->val;
        ++(*pi);
        _preOrder(root->left, a, pi);
        _preOrder(root->right, a, pi);
    }
}

int* preorderTraversal(struct TreeNode* root, int* returnSize){
    int* a, i;
    *returnSize = BSize(root);
    a = (int*) malloc(sizeof(int) * (*returnSize));
    i = 0;
    _preOrder(root, a, &i);
    return a;  
}

中序遍历: https://leetcode.cn/problems/binary-tree-inorder-traversal/description/

c 复制代码
int BSize(struct TreeNode* root)
{
    if(root == NULL)
        return 0;
    return BSize(root->left)
        + BSize(root->right) + 1;
}

void _InOrder(struct TreeNode* root, int* a, int* pi)
{
    if(root)
    {
        
        _InOrder(root->left, a, pi);
        a[*pi] = root->val;
        ++(*pi);
        _InOrder(root->right, a, pi);
    }
}
int* inorderTraversal(struct TreeNode* root, int* returnSize){
    int* a, i;
    *returnSize = BSize(root);
    a = (int*) malloc(sizeof(int) * (*returnSize));
    i = 0;
    _InOrder(root, a, &i);
    return a;
}

后序遍历: https://leetcode.cn/problems/binary-tree-postorder-traversal/description/

c 复制代码
int BSize(struct TreeNode* root)
{
    if(root == NULL)
        return 0;
    return BSize(root->left)
        + BSize(root->right) + 1;
}

void _postorderTraversal(struct TreeNode* root, int* a, int* pi)
{
    if(root)
    {
        _postorderTraversal(root->left, a, pi);
        _postorderTraversal(root->right, a, pi);
        a[*pi] = root->val;
        ++(*pi);
    }
}
int* postorderTraversal(struct TreeNode* root, int* returnSize){
    int* a, i;
    *returnSize = BSize(root);
    a = (int*) malloc(sizeof(int) * (*returnSize));
    i = 0;
    _postorderTraversal(root, a, &i);
    return a;
}

二叉树的遍历,先计算出二叉树的节点个数,再申请结点数量的空间,然后再用遍历的思想将每一个节点值放入到数组对应的位置,然后返回数组即可。

二叉树的构建及遍历

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

c 复制代码
#include <stdio.h>
#include <malloc.h>

typedef struct BTNode
{
    char _data;
    struct BTNode* _left;
    struct BTNode* _right;
}BTNode;

//中序遍历
void Inorder(BTNode* root)
{
    if(root)
    {
        Inorder(root->_left);
        printf("%c ", root->_data);
        Inorder(root->_right);
    }
}

BTNode* CreatBTree(char* str, int* pi)
{
    if(str[*pi]!= '#')
    {
        //当前节点非空,则创建当前节点
        BTNode*root=(BTNode*)malloc(sizeof(BTNode));
        root->_data = str[*pi];
        //字符位置向后移动一个位置
        ++(*pi);
        //创建左子树
        root->_left=CreatBTree(str,pi);
        //字符位置向后移动一个位置
        ++(*pi);
        //创建右子树
        root->_right=CreatBTree(str,pi);
        return root;
    }
    else
        return NULL;  //如果是空节点,则返回NULL
}

int main()
{
    char str[101];
    int i = 0;
    //读入字符串
    scanf("%s", str);
    //创建二叉树
    BTNode* root = CreatBTree(str, &i);
    //中序打印二叉树
    Inorder(root);
    printf("\n");
    return 0;
}
相关推荐
XH华4 小时前
初识C语言之二维数组(下)
c语言·算法
南宫生4 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
不想当程序猿_5 小时前
【蓝桥杯每日一题】求和——前缀和
算法·前缀和·蓝桥杯
落魄君子5 小时前
GA-BP分类-遗传算法(Genetic Algorithm)和反向传播算法(Backpropagation)
算法·分类·数据挖掘
菜鸡中的奋斗鸡→挣扎鸡5 小时前
滑动窗口 + 算法复习
数据结构·算法
Lenyiin5 小时前
第146场双周赛:统计符合条件长度为3的子数组数目、统计异或值为给定值的路径数目、判断网格图能否被切割成块、唯一中间众数子序列 Ⅰ
c++·算法·leetcode·周赛·lenyiin
郭wes代码5 小时前
Cmd命令大全(万字详细版)
python·算法·小程序
scan7245 小时前
LILAC采样算法
人工智能·算法·机器学习
菌菌的快乐生活6 小时前
理解支持向量机
算法·机器学习·支持向量机
大山同学6 小时前
第三章线性判别函数(二)
线性代数·算法·机器学习