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

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

中序遍历序列,           ======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. php函数unserialize数据返回false问题分析

    unserialize的这个问题是由一个emlog论坛用户在使用时报错而发现的 问题表现情况如下: emlog缓存的保存方式是将php的数据对象(数组)序列化(serialize)后以文件的形式存放, ...

  2. solr6.5的分词

    1.配置solr6.5自带中文分词.复制/usr/local/solr/contrib/analysis-extras/lucene-libs/lucene-analyzers-smartcn-6.5 ...

  3. MFC添加菜单资源与菜单执行函数的两种命令形式

    添加资源->新建一个菜单资源->选择相应的对话框 菜单的执行函数命令形式: COMMAD 是指点击菜单后的执行命令 UPDATE_COMMAND_UI 是指点击菜单后菜单状态的函数

  4. python高级语法进阶

    python中几个比较难懂概念进阶. 迭代器 实现了迭代器协议的容器对象,基于如下两个方法: __next__:返回容器的下一个元素 __iter__:返回迭代器本身 由此可见,如果要自定义一个迭代器 ...

  5. maven filters 和 resource

    1 filter 1.1 用途 对多个配置文件进行选择. 1.2 选择的依据 1.3 使用的方式 第一,在<resource>标签下面加<filtering>标签,并且< ...

  6. 安装Eclipsemaven插件

    Maven的Eclipse插件m2eclipse的安装 The goal of the m2ec project is to provide a first-class Apache Maven su ...

  7. SAP内表转XML文件

    今天有个兄弟问如何实现以XML的方式输出内表的内容,这个问题我以前好像没有写过.倒不是不会写,而是写的方法太多了,有极其简单的,也有很复杂的,而且网上资料也很多. 找到以前写的一个程序,稍微修改了一下 ...

  8. 排序算法-python版

    总结了一下常见集中排序的算法 归并排序 归并排序也称合并排序,是分治法的典型应用.分治思想是将每个问题分解成个个小问题,将每个小问题解决,然后合并. 具体的归并排序就是,将一组无序数按n/2递归分解成 ...

  9. python基础14 ---函数模块4(configparser模块)

    configparser模块 一.configparser模块 1.什么是configparser模块:configparser模块操作配置文件,配置文件的格式与windows ini和linux的c ...

  10. 【leetcode刷题笔记】Binary Tree Inorder Traversal

    Given a binary tree, return the inorder traversal of its nodes' values. For example:Given binary tre ...