• 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 
    
  • 相关阅读:
    [C语言嵌入式系统编程修炼] 软件架构与内存操作篇
    [C陷阱和缺陷] 第2章 语法“陷阱”
    DAO是什么技术
    Java泛型:类型擦除
    Java泛型:泛型类、泛型接口和泛型方法
    定义泛型接口
    java,<E>什么意思?
    java List 去重(两种方式)
    java中List集合及其遍历详解
    java 遍历arrayList的四种方法
  • 原文地址:https://www.cnblogs.com/fanlumaster/p/14088280.html
Copyright © 2020-2023  润新知