zoukankan      html  css  js  c++  java
  • 【006】重建二叉树

    【面试题006】重建二叉树 

    重建二叉树,

    在前序遍历和中序遍历两个序列中,确定了根结点的值,进而分别找到了左右子树对应的序列;

    递归的构建二叉树。

    ConstructBinaryTree.cpp:

    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
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
     
    #include <iostream>
    #include <exception>
    #include <cstdio>
    #include "BinaryTree.h"

    using namespace std;

    BinaryTreeNode *ConstructCore(
    int *startPreorder, int *endPreorder, int *startInorder, int *endInorder);

    BinaryTreeNode *Construct(int *preorder, int *inorder, int length)
    {
        if(preorder == NULL || inorder == NULL || length <= 0)
            return NULL;

        return ConstructCore(preorder, preorder + length - 1,
                             inorder, inorder + length - 1);
    }

    BinaryTreeNode *ConstructCore
    (
        int *startPreorder, int *endPreorder,
        int *startInorder, int *endInorder
    )
    {
        // 前序遍历序列的第一个数字是根结点的值
        int rootValue = startPreorder[0];
        BinaryTreeNode *root = new BinaryTreeNode();
        root->m_nValue = rootValue;
        root->m_pLeft = root->m_pRight = NULL;

        if(startPreorder == endPreorder)
        {
            if(startInorder == endInorder && *startPreorder == *startInorder)
                return root;
            else
                throw std::exception();
        }

        // 在中序遍历中找到根结点的值
        int *rootInorder = startInorder;
        while(rootInorder <= endInorder && *rootInorder != rootValue)
            ++ rootInorder;

        if(rootInorder == endInorder && *rootInorder != rootValue)
            throw std::exception();

        int leftLength = rootInorder - startInorder;
        int *leftPreorderEnd = startPreorder + leftLength;
        if(leftLength > 0)
        {
            // 构建左子树
            root->m_pLeft = ConstructCore(startPreorder + 1, leftPreorderEnd,
                                          startInorder, rootInorder - 1);
        }
        if(leftLength < endPreorder - startPreorder)
        {
            // 构建右子树
            root->m_pRight = ConstructCore(leftPreorderEnd + 1, endPreorder,
                                           rootInorder + 1, endInorder);
        }

        return root;
    }

    // 普通二叉树
    //              1
    //           /     
    //          2       3
    //         /       / 
    //        4       5   6
    //                  /
    //          7       8
    int main()
    {

        const int length = 8;
        int preorder[length] = {12473568};
        int inorder[length] = {47215386};

        printf("The preorder sequence is: ");
        for(int i = 0; i < length; ++ i)
            printf("%d ", preorder[i]);
        printf(" ");

        printf("The inorder sequence is: ");
        for(int i = 0; i < length; ++ i)
            printf("%d ", inorder[i]);
        printf(" ");

        try
        {
            BinaryTreeNode *root = Construct(preorder, inorder, length);
            PrintTree(root);

            DestroyTree(root);
        }
        catch(std::exception &exception)
        {
            printf("Invalid Input. ");
        }
        return 0;
    }

    运行结果:

    The preorder sequence is: 1 2 4 7 3 5 6 8
    The inorder sequence is: 4 7 2 1 5 3 8 6
     
    value of this node is: 1
    value of its left child is: 2.
    value of its right child is: 3.
     
    value of this node is: 2
    value of its left child is: 4.
    right child is null.
     
    value of this node is: 4
    left child is null.
    value of its right child is: 7.
     
    value of this node is: 7
    left child is null.
    right child is null.
     
    value of this node is: 3
    value of its left child is: 5.
    value of its right child is: 6.
     
    value of this node is: 5
    left child is null.
    right child is null.
     
    value of this node is: 6
    value of its left child is: 8.
    right child is null.
     
    value of this node is: 8
    left child is null.
    right child is null.
     

    BinaryTree.h:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    #ifndef _BINARY_TREE_H_
    #define _BINARY_TREE_H_

    struct BinaryTreeNode
    {
        int                    m_nValue;
        BinaryTreeNode        *m_pLeft;
        BinaryTreeNode        *m_pRight;
    };

    BinaryTreeNode *CreateBinaryTreeNode(int value);
    void ConnectTreeNodes(
        BinaryTreeNode *pParent, BinaryTreeNode *pLeft, BinaryTreeNode *pRight);
    void PrintTreeNode(BinaryTreeNode *pNode);
    void PrintTree(BinaryTreeNode *pRoot);
    void DestroyTree(BinaryTreeNode *pRoot);


    #endif /*_BINARY_TREE_H_*/

    BinaryTree.cpp:

    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
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
     

    #include <iostream>
    #include <cstdio>
    #include "BinaryTree.h"

    using namespace std;
    BinaryTreeNode *CreateBinaryTreeNode(int value)
    {
        BinaryTreeNode *pNode = new BinaryTreeNode();
        pNode->m_nValue = value;
        pNode->m_pLeft = NULL;
        pNode->m_pRight = NULL;

        return pNode;
    }

    void ConnectTreeNodes(BinaryTreeNode *pParent,
                          BinaryTreeNode *pLeft, BinaryTreeNode *pRight)
    {
        if(pParent != NULL)
        {
            pParent->m_pLeft = pLeft;
            pParent->m_pRight = pRight;
        }
    }

    void PrintTreeNode(BinaryTreeNode *pNode)
    {
        if(pNode != NULL)
        {
            printf("value of this node is: %d ", pNode->m_nValue);

            if(pNode->m_pLeft != NULL)
                printf("value of its left child is: %d. ",
                       pNode->m_pLeft->m_nValue);
            else
                printf("left child is null. ");

            if(pNode->m_pRight != NULL)
                printf("value of its right child is: %d. ",
                       pNode->m_pRight->m_nValue);
            else
                printf("right child is null. ");
        }
        else
        {
            printf("this node is null. ");
        }

        printf(" ");
    }

    void PrintTree(BinaryTreeNode *pRoot)
    {
        PrintTreeNode(pRoot);

        if(pRoot != NULL)
        {
            if(pRoot->m_pLeft != NULL)
                PrintTree(pRoot->m_pLeft);

            if(pRoot->m_pRight != NULL)
                PrintTree(pRoot->m_pRight);
        }
    }

    void DestroyTree(BinaryTreeNode *pRoot)
    {
        if(pRoot != NULL)
        {
            BinaryTreeNode *pLeft = pRoot->m_pLeft;
            BinaryTreeNode *pRight = pRoot->m_pRight;

            delete pRoot;
            pRoot = NULL;

            DestroyTree(pLeft);
            DestroyTree(pRight);
        }
    }

    Makefile:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    .PHONY:clean  
    CPP=g++  
    CFLAGS=-Wall -g  
    BIN=test  
    OBJS=ConstructBinaryTree.o BinaryTree.o  
    LIBS=  
    $(BIN):$(OBJS)  
        $(CPP) $(CFLAGS) $^ -o $@ $(LIBS)  
    %.o:%.cpp  
        $(CPP) $(CFLAGS) -c $< -o $@  
    clean:  
        rm -f *.o $(BIN)  



     

     
  • 相关阅读:
    day4
    day3
    day2
    day1
    spring-boot-note
    spring-boot-cli
    jquery ajax rest invoke
    spring-boot
    docker mysql
    jpa OneToMany
  • 原文地址:https://www.cnblogs.com/codemylife/p/3679707.html
Copyright © 2011-2022 走看看