【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("\n");

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

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

        DestroyTree(root);
    }
    catch(std::exception &exception)
    {
        printf("Invalid Input.\n");
    }
    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\n", pNode->m_nValue);

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

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

    printf("\n");
}

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)  



 

 
posted @ 2014-04-22 08:51  z陵  阅读(661)  评论(0编辑  收藏  举报