• [LeetCode]链式二叉树相关题目(c语言实现)


    LeetCode965. 单值二叉树

    题目
    在这里插入图片描述

    Oj链接

    思路

    一棵树的所有值都是一个值, 那么就可以认为每个结点的左右孩子都和该结点的值相等
    将一棵树分为根 左子树 右子树, 如果值不相等直接返回 false

    先判断根结点的左右孩子是否和根结点的值一样

    • 如果一样,先判断左子树,再判断右子树,最后返回两结果的逻辑与结果
    • 如果不一样,直接返回false,

    代码实现

    bool isUnivalTree(struct TreeNode* root)
    {
        if (root == NULL)   
            return true;
        
        if (root->left && root->val != root->left->val)     //如果左子树存在并且值不等, 返回false
            return false;
        
        if (root->right && root->val != root->right->val)   //如果右子树存在并且值不等, 返回false
            return false;
        
        return isUnivalTree(root->left) && isUnivalTree(root->right);   //左子树为单值 && 右子树为单值
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    LeetCode100. 相同的树

    题目
    在这里插入图片描述

    Oj链接

    思路

    • 如果两个树都为空, 则两树相等;
    • 如果两个树中只有一个是空, 那么两数必然不相等.
    • 如果两个数都不为空, 则先判断两树的根结点是否值一样.
      • 若一样, 继续递归调用判断左子树和右子树是否都对应相等;
      • 若不一样,直接向上一层返回false

    代码实现

    bool isSameTree(struct TreeNode* p, struct TreeNode* q)
    {
        if (p == NULL && q == NULL) //如果两个结点都是空, 返回true
        {
            return true;
        }
    
        if (p == NULL || q == NULL) //在两个结点不同时为空的情况下, 有一个为空直接返回false
        {
            return false;
        }
    
        //剩余就只有两结点都不为空的情况了
        if (p->val != q->val)
        {
            return false;
        }
    
        return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    LeetCode101. 对称二叉树

    题目
    在这里插入图片描述

    Oj链接

    思路
    和判断两树是否一样的思路差不多

    一个树是对称二叉树的条件就是:

    1. 根结点的左右孩子一样
    2. 左子树的左子树 和 右子树的右子树 一样
    3. 左子树的右子树 和 右子树的左子树 一样

    由此对于左右子树的判断我们可以创建一个递归函数, 类似于判断两树是否一样, 函数参数是两个树

    • 如果两个树都是空, 则两树对称
    • 如果两个树中只有一个是空, 则两树不对称
    • 如果两个数都不为空, 则判断 左左和右右是否相等, 左右和右左是否相同

    代码实现

    bool isSymmetricTree(struct TreeNode* q, struct TreeNode* p)
    {
        if (q == NULL && p == NULL)
            return true;
        
        if (q == NULL || p == NULL)
            return false;
        
        if (q->val != p->val)
            return false;
        
        return isSymmetricTree(q->left, p->right) 
            && isSymmetricTree(q->right, p->left);
    }
    
    bool isSymmetric(struct TreeNode* root)
    {
        if (root == NULL)
            return true;
        return isSymmetricTree(root->left, root->right);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    LeetCode144. 二叉树的前序遍历

    LeetCode94. 二叉树的中序遍历

    LeetCode145. 二叉树的后序遍历

    三题类似,这里直接一起贴上来
    题目
    二叉树的前序遍历。 Oj链接

    二叉树中序遍历Oj链接

    二叉树的后序遍历 。Oj链接

    思路
    就拿前序遍历来说, 对于普通打印的前序遍历就不多说了, 相关可以看我的文章:链式二叉树

    在这里, 主要是理解题目意思, 首先我们来看题目给的接口函数描述

    int* preorderTraversal(struct TreeNode* root, int* returnSize);
    
    • 1

    函数需要我们将前序遍历的结果存到一个数组当中, 并且将数组返回, 这就需要我们动态开辟一段空间.
    int* returnSize表示我们同时要返回二叉树的结点个数, 通过传址调用返回.

    1. 获得二叉数结点个数, 并开辟同样元素个数空间的数组空间
    2. 前序遍历二叉树, 自己创建一个递归函数, 为了方便递归调用来存放数据到数组, 将数组下标传址调用

    代码实现

    • 前序遍历
    // 二叉树结点个数
    int binaryTreeSize(struct TreeNode* root)
    {
        if (root == NULL)
        {
            return 0;
        }
    
        return 1 + binaryTreeSize(root->left) + binaryTreeSize(root->right);
    }
    
    void preOrder(struct TreeNode* root, int* a, int* i)
    {
        if (root == NULL)
        {
            return;
        }
    
        a[(*i)++] = root->val;
        preOrder(root->left, a, i);
        preOrder(root->right, a, i);
    }
    //首先得到二叉树结点个数, 根据个数开辟数组空间
    //接着前序遍历二叉树, 将结点的值按序存入数组中, 注意函数参数传址调用
    int* preorderTraversal(struct TreeNode* root, int* returnSize)
    {
        *returnSize = binaryTreeSize(root);
        int* a = (int*)malloc(sizeof(int) * (*returnSize));
    
        int index = 0;
        preOrder(root, a, &index);
    
        return a;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 中序遍历
    int TreeSize(struct TreeNode* root)
    {
        return root == NULL ? 0 : 1 + TreeSize(root->left) + TreeSize(root->right);
    }
    
    void inOrder(struct TreeNode* root, int* a, int* pi)
    {
        if (root == NULL)
        {
            return ;
        }
    
        inOrder(root->left, a, pi);
        a[(*pi)++] = root->val;
        inOrder(root->right, a, pi);
    }
    int* inorderTraversal(struct TreeNode* root, int* returnSize)
    {
        *returnSize = TreeSize(root);
        int* a = (int*)malloc(sizeof(int) * (*returnSize));
    
        int index = 0;
        inOrder(root, a, &index);
    
        return a;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 后序遍历
    int TreeSize(struct TreeNode* root)
    {
        return root == NULL ? 0 : 1 + TreeSize(root->left) + TreeSize(root->right);
    }
    
    void postOrder(struct TreeNode* root, int* a, int* pi)
    {
        if (root == NULL)
        {
            return;
        }    
    
        postOrder(root->left, a, pi);
        postOrder(root->right, a, pi);
        a[(*pi)++] = root->val;
    }
    int* postorderTraversal(struct TreeNode* root, int* returnSize)
    {
        *returnSize = TreeSize(root);
        int* a = (int*)malloc(sizeof(int) * (*returnSize));
    
        int index = 0;
        postOrder(root, a, &index);
        return a;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    LeetCode572. 另一棵树的子树

    题目
    在这里插入图片描述

    Oj链接

    思路

    深度搜索每一个结点, 如果结点与subRoot的根结点相同, 则进行判断以这两个结点为根结点的树是否相同

    这里需要用到前面用到的判断两个树是否一样的函数代码.

    1. 如果 rootsubRoot 都为空, 则直接返回 true
    2. 如果 rootsubRoot 两个只有有一个为空, 则直接返回 false
    3. 此时只剩下两者都不为空的情况, 深度搜索判断 root 每个结点是否和 subRoot 的根结点一样
    • 如果一样, 则使用 isSameTree进行判断
    • 如果不一样, 继续深度搜索
    1. 最后将左右子树的两个结果经过逻辑或得到结果
    bool isSameTree(struct TreeNode* p, struct TreeNode* q)
    {
        if (p == NULL && q == NULL) //如果两个结点都是空, 返回true
        {
            return true;
        }
    
        if (p == NULL || q == NULL) //在两个结点不同时为空的情况下, 有一个为空直接返回false
        {
            return false;
        }
    
        //剩余就只有两结点都不为空的情况了
        if (p->val != q->val)
        {
            return false;
        }
    
        return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
    }
    
    // 如果根结点对应的树是subRoot, 则返回true
    // 如果不是 寻找左子树有没有
    //          寻找右子树有没有
    bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot)
    {
        if (root == NULL && subRoot == NULL)
        {
            return true;
        }
    
        if (root == NULL || subRoot == NULL)
        {
            return false;
        }
        
        if (root->val == subRoot->val)
        {
            if (isSameTree(root, subRoot))
            {
                return true;
            }
        }
        
    
        return isSubtree(root->left, subRoot) 
        || isSubtree(root->right, subRoot);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
  • 相关阅读:
    论文详读:IMPROVING CONVOLUTIONAL MODELS FOR HANDWRITTEN TEXT RECOGNITION
    探讨Unity新的收费模式:对开发者与游戏行业的影响、负面因素的解析及面对挑战的建议
    如何备考PMP才能一次通过?
    构建微波和毫米波自动测试系统需要考虑哪些因素?(二)
    linux检测系统是否被入侵(完整篇)
    ARM-day9
    云原生技术 --- k8s工作负载之pod的学习与理解
    GLTF格式解析
    (附源码)spring boot动力电池数据管理系统 毕业设计 301559
    vue判断图片是否可用访问,不能访问就重新获取
  • 原文地址:https://blog.csdn.net/Kuzuba/article/details/133756442