zoukankan      html  css  js  c++  java
  • 105. 从前序和中序遍历序列构造二叉树

    题目描述

    20201204234719

    链接: https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/

    分析

    二叉树前序遍历的顺序为:

    • 先遍历根节点;
    • 随后递归地遍历左子树;
    • 最后递归地遍历右子树。

    二叉树中序遍历的顺序为:

    • 先递归地遍历左子树;
    • 随后遍历根节点;
    • 最后递归地遍历右子树。

    在「递归」地遍历某个子树的过程中,我们也是将这颗子树看成一颗全新的树,按照上述的顺序进行遍历。挖掘「前序遍历」和「中序遍历」的性质,我们就可以得出根据前序和中序遍历构造二叉树的做法。

    代码

    struct TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int inorderSize){
        struct TreeNode *newNode;
        int p = 0;
        int i = 0;
    
        // 去除输入不合理的情况
        if (preorder == NULL || inorder == NULL)
        {
            return NULL;
        }
        if (preorderSize <= 0 || inorderSize <= 0)
        {
            return NULL;
        }
    
        newNode = (struct TreeNode *) malloc(sizeof(struct TreeNode));
        newNode->val = preorder[p]; // 根据前序取出根节点
        newNode->left = NULL;
        newNode->right = NULL;
    
        for (i = 0; i < inorderSize; i++)
        {
            // 在中序中找到根节点,然后递归
            if (inorder[i] == newNode->val)
            {
                newNode->left = buildTree(&preorder[p + 1], i, inorder, i); // 递归构造左子树
                newNode->right = buildTree(&preorder[p + i + 1], preorderSize - i - 1, &inorder[i + 1],
                                           inorderSize - i - 1); // 递归构造右子树
                break;
            }
        }
    
        return newNode;
    }
    

    完整的测试代码

    #include <stdio.h>
    #include <malloc.h>
    
    // Definition for a binary tree node.
    struct TreeNode {
        int val;
        struct TreeNode *left;
        struct TreeNode *right;
    };
    
    typedef struct TreeNode *BinTree;
    
    
    struct TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int inorderSize)
    {
        struct TreeNode *newNode;
        int p = 0;
        int i = 0;
    
        // 去除输入不合理的情况
        if (preorder == NULL || inorder == NULL)
        {
            return NULL;
        }
        if (preorderSize <= 0 || inorderSize <= 0)
        {
            return NULL;
        }
    
        newNode = (struct TreeNode *) malloc(sizeof(struct TreeNode));
        newNode->val = preorder[p]; // 根据前序取出根节点
        newNode->left = NULL;
        newNode->right = NULL;
    
        for (i = 0; i < inorderSize; i++)
        {
            // 在中序中找到根节点,然后递归
            if (inorder[i] == newNode->val)
            {
                newNode->left = buildTree(&preorder[p + 1], i, inorder, i); // 递归构造左子树
                newNode->right = buildTree(&preorder[p + i + 1], preorderSize - i - 1, &inorder[i + 1],
                                           inorderSize - i - 1); // 递归构造右子树
                break;
            }
        }
    
        return newNode;
    }
    
    void freeTree(struct TreeNode *T)
    {
        if (NULL == T)
            return;
    
        freeTree(T->left);
        freeTree(T->right);
        freeTree(T);
    }
    
    // 先序
    void PreOrderTraversal(struct TreeNode *T)
    {
        if (T) {
            printf("%d ", T->val);
            PreOrderTraversal(T->left);
            PreOrderTraversal(T->right);
        }
    }
    
    // 中序
    void InOrderTraversal(struct TreeNode *T) {
        if (T) {
            InOrderTraversal(T->left);
            printf("%d ", T->val);
            InOrderTraversal(T->right);
        }
    }
    
    // 后序
    void PostOrderTraversal(struct TreeNode *T) {
        if (T) {
            PostOrderTraversal(T->left);
            PostOrderTraversal(T->right);
            printf("%d ", T->val);
        }
    }
    
    // 测试
    int main()
    {
        int preorder[5] = {3, 9, 20, 15, 7};
        int inorder[5] = {9, 3, 15, 20, 7};
    
        BinTree buildedTree = buildTree(preorder, 5, inorder, 5);
    
        printf("前序遍历:");
        PreOrderTraversal(buildedTree);
        printf("
    ");
        printf("中序遍历:");
        InOrderTraversal(buildedTree);
        printf("
    ");
        printf("后序遍历:");
        PostOrderTraversal(buildedTree);
    
        return 0;
    }
    

    输出结果:

    前序遍历:3 9 20 15 7 
    中序遍历:9 3 15 20 7 
    后序遍历:9 15 7 20 3 
    
  • 相关阅读:
    华为S570028TPLIAC 快速清除接口配置
    【银河麒麟操作系统V10】【服务器】 创建bond
    VMware Horizon 组件如何组成在一起
    Horizon桌面部署问题总结
    overlay网络技术之VxLAN详解
    Brocade 光纤交换机级联配置
    nginx反向代理400绕过学习
    dbeaver:可以作为简单报表、报警等用途的强大sql ide工具
    linuxpython2.x:安装cx_Oracle包:从最初、最原始的发行版状态:不依赖pip
    Linux 网卡限速:wondershaper 1.4.1@20211111:这是当前的最新版
  • 原文地址:https://www.cnblogs.com/fanlumaster/p/14088280.html
Copyright © 2011-2022 走看看