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

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

前序遍历序列,           O=================

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

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

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

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

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

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

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

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

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

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

笔记:

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

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

Given preorder and inorder 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
164
165
166
167
168
169
 
#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> &preorder, int left1, int right1, vector<int> &inorder, int left2, int right2)
{
    //对错误输入的判断
    if(right1 - left1 != right2 - left2)
    {
        return NULL;
    }
    if(right1 >= preorder.size() || right2 >= inorder.size())
    {
        return NULL;
    }

if(left1 == right1 && left2 == right2)
    {
        //只有一个节点的情况
        TreeNode *root = new TreeNode(preorder[left1]);
        return root;
    }
    else if(left1 < right1 && left2 < right2)
    {
        //多个节点的情况,生成当前的根节点
        TreeNode *root = new TreeNode(preorder[left1]);
        int i;
        for(i = left2; i <= right2; i++)
        {
            //找到中序的当前根节点的位置
            if(inorder[i] == preorder[left1])
            {
                break;
            }
        }
        if(i > right2)
        {
            return NULL;
        }
        /*
         * 递归的构建左边二叉树的和右边的二叉树
         * 左子树{left1 + 1, i - 1}                   前序[left1 + 1, left1 + i - left2]           中序[left2, i - 1]
         * 右子树{left1 + i - left2 +1, right2}       前序[left1 + i - left2 + 1, right1]          中序[i + 1, right2]
         * 前序以left1 + i - left2为分割点
         * 中序以i为分割点
         */
        root->left = build(preorder, left1 + 1, left1 + i - left2, inorder, left2, i - 1);
        root->right = build(preorder, left1 + i - left2 + 1, right1, inorder, i + 1, right2);
        return root;
    }
    else
    {
        return NULL;
    }

}

TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder)
{
    return build(preorder, 0, preorder.size() - 1, inorder, 0, inorder.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 pre[7] = {6, 7, 1, 4, 3, 5, 2};
    int in[7] = {1, 7, 3, 4, 5, 6, 2};
    vector<int> preorder(pre, pre + 7), inorder(in, in + 7);

TreeNode *root = buildTree(preorder, inorder);

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;
    }
    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);
    }
}

 
 
												

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

  1. [LeetCode] Construct Binary Tree from Preorder and Inorder Traversal 由先序和中序遍历建立二叉树

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

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

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

  3. [Swift]LeetCode105. 从前序与中序遍历序列构造二叉树 | Construct Binary Tree from Preorder and Inorder Traversal

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

  4. LeetCode105 从前序和中序序列构造二叉树

    题目描述: 根据一棵树的前序遍历与中序遍历构造二叉树. 注意:你可以假设树中没有重复的元素. 例如,给出 前序遍历 preorder = [3,9,20,15,7] 中序遍历 inorder = [9 ...

  5. LeetCode 105. Construct Binary Tree from Preorder and Inorder Traversal 由前序和中序遍历建立二叉树 C++

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

  6. LeetCode 105. 从前序与中序遍历序列构造二叉树(Construct Binary Tree from Preorder and Inorder Traversal)

    题目描述 根据一棵树的前序遍历与中序遍历构造二叉树. 注意:你可以假设树中没有重复的元素. 例如,给出 前序遍历 preorder = [3,9,20,15,7] 中序遍历 inorder = [9, ...

  7. Leetcode105. Construct Binary Tree from Preorder and Inorder Traversal前序与中序构造二叉树

    根据一棵树的前序遍历与中序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 例如,给出 前序遍历 preorder = [3,9,20,15,7] 中序遍历 inorder = [9,3,15 ...

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

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

  9. LeetCode OJ:Construct Binary Tree from Preorder and Inorder Traversal(从前序以及中序遍历结果中构造二叉树)

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

随机推荐

  1. Redis(Windows安装方法与Java调用实例 & 配置文件参数说明 & Java使用Redis所用Jar包 & Redis与Memcached区别 & redis-cli.exe命令及示例)

    Windows下Redis的安装使用 0.前言 因为是初次使用,所以是在windows下进行安装和使用,参考了几篇博客,下面整理一下 1.安装Redis 官方网站:http://redis.io/ 官 ...

  2. 卸载系统自带libevent

    rpm -qa|grep libevent yum remove libevent* 或 rpm -e --nodeps --allmatches libevent*

  3. phpcms的基础知识和配置

    一.设置界面 1.站点设置:相当于服务器上的站点 (1)站点修改:“关键词”和“描述”的修改,便于网络优化和搜索引擎对本网站的搜索. (2)点击站点后边的修改,模板的修改,引用自己模板 2.基本设置: ...

  4. 【BZOJ3640】JC的小苹果 概率DP+高斯消元

    [BZOJ3640]JC的小苹果 Description 让我们继续JC和DZY的故事. “你是我的小丫小苹果,怎么爱你都不嫌多!” “点亮我生命的火,火火火火火!” 话说JC历经艰辛来到了城市B,但 ...

  5. 【网络与系统安全】20179209 wireshark和nmap实验

    TCP三次握手包 在进行实验前,先梳理一遍TCP三次握手的过程,这个图是我本科学网络时画过不少于十遍的图,我觉得非常有纪念意义. 稍作解释,第一次握手,客户端发起请求连接,发送一个标志位为SYN的ip ...

  6. 我的Android进阶之旅------>四种呼叫转移场景

    运行商为我们提供了如下4中呼叫转移场景: 1.始终进行呼叫转移:不管当前手机处于何种状态,来电都会被转移到指定的电话号码上.在使用这种呼叫转移时应当非常小心,如果启用了这种呼叫转移,你可就永远也接不着 ...

  7. git本地分支管理

    查看分支:git branch创建分支:git branch dev重命名分支:git branch -m dev dev1删除分支:git branch -d dev切换分支:git checkou ...

  8. 丢失vcruntime140.dll

    我在php7安装yaf时报了标题所提示的错误信息. 解决方案是:下载vc++2015 并安装 链接如下:https://www.microsoft.com/zh-cn/download/confirm ...

  9. SAP 定价

    近几天做门店团购销售订单上传SAP接口程序,SO创建测试过程中, 遇到定价问题,同事在定价过程的增强过不了. VOFM 了解到定价过程是个非常复杂的环节,此处出现程序处理过程中ZMP0定价条件下的价格 ...

  10. 用cocos2d-html5做的消除类游戏《英雄爱消除》——概述

    在bbs.html5china.com论坛学习了MV和老马的小熊蘑菇后我也自己模仿他们做了这样子一个游戏,权当技术交流学习,现在附上游戏截图和源码. 游戏截图: 1.系统菜单界面: 2.游戏界面 3. ...