我们都知道,已知中序和后序的序列是可以唯一确定一个二叉树的。

初始化时候二叉树为:==================

中序遍历序列,           ======O===========

后序遍历序列,           =================O

红色部分是左子树,黑色部分是右子树,O是根节点

如上图所示,O是根节点,由后序遍历可知,

根据这个O可以把找到其在中序遍历当中的位置,进而,知道当前这个根节点O的左子树的前序遍历和中序遍历序列的范围。

以及右子树的前序遍历和中序遍历序列的范围。

到这里返现出现了重复的子问题,而且子问题的规模没有原先的问题大,即红色部分和黑色部分

而联系这两个子问题和原先的大问题的纽带是这个找到的根节点。

可以选择用递归来解决这个问题,递归的结束条件是子问题序列里面只有一个元素。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

给定一个二叉树的中序和后序遍历序列,构造这个二叉树。

笔记:

你可以假定,这棵树里面没有重复的节点。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Given inorder and postorder traversal of a tree, construct the binary tree.

Note:
You may assume that duplicates do not exist in the tree.

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 
test.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
 
#include <iostream>
#include <cstdio>
#include <stack>
#include <vector>
#include "BinaryTree.h"

using namespace std;

/**
 * Definition for binary tree
 * struct TreeNode {
 * int val;
 * TreeNode *left;
 * TreeNode *right;
 * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
TreeNode *build(vector<int> &inorder, int left1, int right1, vector<int> &postorder, int left2, int right2)
{

if(right1 - left1 != right2 - left2)
    {
        return NULL;
    }
    if(right1 >= inorder.size() || right2 >= postorder.size())
    {
        return NULL;
    }

//递归结束条件
    if(left1 == right1 && left2 == right2)
    {
        TreeNode *root = new TreeNode(inorder[left1]);
        return root;
    }
    else if(left1 < right1 && left2 < right2)
    {

TreeNode *root = new TreeNode(postorder[right2]);
        int i;
        for(i = right1; i >= left1; i--)
        {
            //找到中序遍历的根节点
            if(inorder[i] == postorder[right2])
            {
                break;
            }
        }
        if(i < left1)
        {
            return NULL;
        }
        root->left = build(inorder, left1, i - 1, postorder, left2, right2 + i - right1 - 1);
        root->right = build(inorder, i + 1, right1, postorder, right2 + i - right1, right2 - 1);
        return root;

}
    else
    {
        return NULL;
    }

}

TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder)
{
    return build(inorder, 0, inorder.size() - 1, postorder, 0, postorder.size() - 1);
}

vector<vector<int> > levelOrder(TreeNode *root)
{

vector<vector<int> > matrix;
    if(root == NULL)
    {
        return matrix;
    }
    vector<int> temp;
    temp.push_back(root->val);
    matrix.push_back(temp);

vector<TreeNode *> path;
    path.push_back(root);

int count = 1;
    while(!path.empty())
    {
        TreeNode *tn = path.front();
        if(tn->left)
        {
            path.push_back(tn->left);
        }
        if(tn->right)
        {
            path.push_back(tn->right);
        }
        path.erase(path.begin());
        count--;

if(count == 0)
        {
            vector<int> tmp;
            vector<TreeNode *>::iterator it = path.begin();
            for(; it != path.end(); ++it)
            {
                tmp.push_back((*it)->val);
            }
            if(tmp.size() > 0)
            {
                matrix.push_back(tmp);
            }
            count = path.size();
        }
    }
    return matrix;
}

// 树中结点含有分叉,
//                  6
//              /       \
//             7         2
//           /   \
//          1     4
//               / \
//              3   5
int main()
{
    TreeNode *pNodeA1 = CreateBinaryTreeNode(6);
    TreeNode *pNodeA2 = CreateBinaryTreeNode(7);
    TreeNode *pNodeA3 = CreateBinaryTreeNode(2);
    TreeNode *pNodeA4 = CreateBinaryTreeNode(1);
    TreeNode *pNodeA5 = CreateBinaryTreeNode(4);
    TreeNode *pNodeA6 = CreateBinaryTreeNode(3);
    TreeNode *pNodeA7 = CreateBinaryTreeNode(5);

ConnectTreeNodes(pNodeA1, pNodeA2, pNodeA3);
    ConnectTreeNodes(pNodeA2, pNodeA4, pNodeA5);
    ConnectTreeNodes(pNodeA5, pNodeA6, pNodeA7);

int in[7] = {1, 7, 3, 4, 5, 6, 2};
    int post[7] = {1, 3, 5, 4, 7, 2, 6};
    vector<int> inorder(in, in + 7), postorder(post, post + 7);

TreeNode *root = buildTree(inorder, postorder);

vector<vector<int> > ans = levelOrder(root);

for (int i = 0; i < ans.size(); ++i)
    {
        for (int j = 0; j < ans[i].size(); ++j)
        {
            cout << ans[i][j] << " ";
        }
        cout << endl;
    }
    DestroyTree(root);
    return 0;
}

结果输出:
6
7 2
1 4
3 5
ps.测试的输出用的是层次遍历
 
BinaryTree.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 
#ifndef _BINARY_TREE_H_
#define _BINARY_TREE_H_

struct TreeNode
{
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

TreeNode *CreateBinaryTreeNode(int value);
void ConnectTreeNodes(TreeNode *pParent,
                      TreeNode *pLeft, TreeNode *pRight);
void PrintTreeNode(TreeNode *pNode);
void PrintTree(TreeNode *pRoot);
void DestroyTree(TreeNode *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
82
83
84
85
86
87
88
89
 
#include <iostream>
#include <cstdio>
#include "BinaryTree.h"

using namespace std;

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */

//创建结点
TreeNode *CreateBinaryTreeNode(int value)
{
    TreeNode *pNode = new TreeNode(value);

return pNode;
}

//连接结点
void ConnectTreeNodes(TreeNode *pParent, TreeNode *pLeft, TreeNode *pRight)
{
    if(pParent != NULL)
    {
        pParent->left = pLeft;
        pParent->right = pRight;
    }
}

//打印节点内容以及左右子结点内容
void PrintTreeNode(TreeNode *pNode)
{
    if(pNode != NULL)
    {
        printf("value of this node is: %d\n", pNode->val);

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

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

printf("\n");
}

//前序遍历递归方法打印结点内容
void PrintTree(TreeNode *pRoot)
{
    PrintTreeNode(pRoot);

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

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

void DestroyTree(TreeNode *pRoot)
{
    if(pRoot != NULL)
    {
        TreeNode *pLeft = pRoot->left;
        TreeNode *pRight = pRoot->right;

delete pRoot;
        pRoot = NULL;

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

 
 

【构建二叉树】02根据中序和后序序列构造二叉树【Construct Binary Tree from Inorder and Postorder Traversal】的更多相关文章

  1. leetcode题解:Construct Binary Tree from Inorder and Postorder Traversal(根据中序和后序遍历构造二叉树)

    题目: Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume ...

  2. [LeetCode] Construct Binary Tree from Inorder and Postorder Traversal 由中序和后序遍历建立二叉树

    Given inorder and postorder traversal of a tree, construct the binary tree. Note: You may assume tha ...

  3. LeetCode 106. Construct Binary Tree from Inorder and Postorder Traversal 由中序和后序遍历建立二叉树 C++

    Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume that ...

  4. [LeetCode] 106. Construct Binary Tree from Inorder and Postorder Traversal 由中序和后序遍历建立二叉树

    Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume that ...

  5. [Swift]LeetCode106. 从中序与后序遍历序列构造二叉树 | Construct Binary Tree from Inorder and Postorder Traversal

    Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume that ...

  6. 106 Construct Binary Tree from Inorder and Postorder Traversal 从中序与后序遍历序列构造二叉树

    给定一棵树的中序遍历与后序遍历,依据此构造二叉树.注意:你可以假设树中没有重复的元素.例如,给出中序遍历 = [9,3,15,20,7]后序遍历 = [9,15,7,20,3]返回如下的二叉树:    ...

  7. 106. Construct Binary Tree from Inorder and Postorder Traversal根据后中序数组恢复出原来的树

    [抄题]: Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assum ...

  8. (二叉树 递归) leetcode 106. Construct Binary Tree from Inorder and Postorder Traversal

    Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume that ...

  9. Construct Binary Tree from Inorder and Postorder Traversal(根据中序遍历和后序遍历构建二叉树)

    根据中序和后续遍历构建二叉树. /** * Definition for a binary tree node. * public class TreeNode { * int val; * Tree ...

随机推荐

  1. 同样的代码在java和c++中结果不同

    #include <iostream> using namespace std; /* run this program using the console pauser or add y ...

  2. EasyDarwin开源流媒体服务器Golang版本:服务端录像功能发布

    EasyDarwin开源流媒体服务器(www.easydarwin.org)现在使用Go版本实现了.最新的代码提交,已经支持了推流(或者拉流)的同时进行本地存储. 本地存储的原理,是在推流的同时启动f ...

  3. oracle 如何完全删除干净

    在安装oracle的时候如果出现了,指定的SID在本机上已经存在.这样的报错的话.这边你肯定是第二次在安装你的oracle了,这里出现这样的错误是你没有吧原先的那些关于oracle的东西给清理干净,这 ...

  4. POJ 2993 Emag eht htiw Em Pleh【模拟画棋盘】

    链接: http://poj.org/problem?id=2993 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=27454#probl ...

  5. sgu Theodore Roosevelt【判断点是否在凸多边形内模板】

    链接: http://acm.sgu.ru/problem.php?contest=0&problem=253 http://acm.hust.edu.cn/vjudge/contest/vi ...

  6. xCode9 一直Indexing

    解决办法:打开终端输入:defaults write com.apple.dt.XCode IDEIndexDisable 1 然后重新打开工程就可以了

  7. MAC 脚本批量启动应用

    1.touch batchStart.sh 2. #!/bin/bash cd /xxx open 1.app open 2.app 3.chmod +x batchStart.sh 4.ok

  8. SAP basis 常用事物

    1.创建一个新的用户 完成client创建和拷贝后,在开始正式工作之前,需要创建新的用户.  用这个用户进行工作.默认ddic和sap*用户不要用于实际的业务.  创建用户的过程很简单,只要以su01 ...

  9. linux 8 -- 管道组合Shell命令进行系统管理

    二十. 通过管道组合Shell命令获取系统运行数据: 1.  输出当前系统中占用内存最多的5条命令:     #1) 通过ps命令列出当前主机正在运行的所有进程.     #2) 按照第五个字段基于数 ...

  10. Kindeditor 函数用途

    1.loadScript  加载文件   2.updateState 更新工具条状态   afterCreate在dom加载的时候执行,dom加载完之前执行的 K.ready dom加载完之后执行   ...