已知二叉树的前序遍历结果和中序遍历结果,请重建原来的二叉树

分析的过程:

1、假设前序遍历的第一个值为a,该值就是原二叉树的根节点。

2、在中序遍历结果中查找a。
则在中序遍历中a前面的节点,就是原二叉树a节点左子树的中序遍历结果;在a后面的节点,就是原二叉树a节点右子树的中序遍历结果。

3、由第二步得到a节点左子树的节点个数为m,那么在前序遍历中a后面的m个节点即为a节点左子树的前序遍历结果;

4、由第二步得到a节点右子树的节点个数为n,那么在前序遍历中最后n个节点即为a节点右子树的前序遍历结果;

由此我们可以得到a节点左子树和右子树的前序遍历和中序遍历结果;

这正符合递归的解决思想。

下面给出算法如下:

#include "stdafx.h"
#include <iostream>
using namespace std;

struct BinaryTreeNode
{
int value;
BinaryTreeNode* leftChild;
BinaryTreeNode* rightChild;
};

BinaryTreeNode* CreateTree(int* pPreVisit, int start1, int end1, int* pMidVisit, int start2, int end2)
{
if(pPreVisit == NULL || pMidVisit == NULL || start1 > end1 || start2 > end2 || (end1 - start1 != end2 - start2))
{
return NULL;
}

BinaryTreeNode* pRootNode = new BinaryTreeNode();
pRootNode->value = pPreVisit[start1];

int index = start2;
while(index < end2)
{
if(pMidVisit[index] == pPreVisit[start1])
{
break;
}
index++;
}

int leftChildStart = ++start1;
int leftChildCount = index - start2;
int leftChildEnd = leftChildStart + leftChildCount - 1;

pRootNode->leftChild = CreateTree(pPreVisit, leftChildStart, leftChildEnd, pMidVisit, start2, index - 1);

int rightChildCount = end2 - index;
int rightChildStart = end1 - rightChildCount  + 1;
pRootNode->rightChild = CreateTree(pPreVisit, rightChildStart, end1, pMidVisit, index + 1, end2);

return pRootNode;
}

int _tmain(int argc, _TCHAR* argv[])
{
int PreVisit[] = {1, 2, 4, 7, 3, 5, 6, 8};
int MidVisit[] = {4, 7, 2, 1, 5, 3, 8, 6};

BinaryTreeNode* pRoot = CreateTree(PreVisit, 0, sizeof(PreVisit)/sizeof(int) - 1, MidVisit, 0, sizeof(MidVisit)/sizeof(int) -1);

char exit;
cin >> exit;
return 0;
}


已知二叉树的前序遍历结果和中序遍历结果,请重建原来的二叉树,布布扣,bubuko.com

时间: 2024-10-06 04:32:42

已知二叉树的前序遍历结果和中序遍历结果,请重建原来的二叉树的相关文章

已知前序(后序)遍历序列和中序遍历序列构建二叉树(Leetcode相关题目)

1.文字描述: 已知一颗二叉树的前序(后序)遍历序列和中序遍历序列,如何构建这棵二叉树? 以前序为例子: 前序遍历序列:ABCDEF 中序遍历序列:CBDAEF 前序遍历先访问根节点,因此前序遍历序列的第一个字母肯定就是根节点,即A是根节点:然后,由于中序遍历先访问左子树,再访问根节点,最后访问右子树,所以我们找到中序遍历中A的位置,然后A左边的字母就是左子树了,也就是CBD是根节点的左子树:同样的,得到EF为根节点的右子树. 将前序遍历序列分成BCD和EF,分别对左子树和右子树应用同样的方法,

已知二叉树的先序遍历序列和中序遍历序列,输出该二叉树的后序遍历序列

题目描述 输入二叉树的先序遍历序列和中序遍历序列,输出该二叉树的后序遍历序列. 输入 第一行输入二叉树的先序遍历序列: 第二行输入二叉树的中序遍历序列. 输出 输出该二叉树的后序遍历序列. 示例输入 ABDCEF BDAECF 示例输出 DBEFCA #include <iostream> #include <cstring> #define MAX 50+3 using namespace std; typedef char Elem_Type; typedef struct B

C++ 根据前序遍历序列和中序遍历序列可以构造唯一的二叉树

文章转载自http://blog.csdn.net/touzani/article/details/1637195 根据前序遍历序列和中序遍历序列可以构造唯一的二叉树. 假设序列为string型 根据前序遍历的特点, 知前序序列(Pre)的首个元素(Pre[0])为根(root), 然后在中序序列(In)中查找此根(Pre[0]), 根据中序遍历特点, 知在查找到的根(root) 前边的序列为左子树, 后边的序列为右子树. 设根前边有left个元素.. 则又有, 在前序序列中, 紧跟着根(roo

七:重建二叉树(根据先序遍历(或者后序遍历)和中序遍历重建二叉树)

对于一颗二叉树,可以根据先序遍历(或者后序遍历)和中序遍历(树中不含重复的数字)重新还原出二叉树. 解析: 1. 先序遍历序列的第一个元素必定是根节点,可以由此获取二叉树的根节点. 2. 根据根节点,在中序遍历序列中查找该节点,由中序遍历的性质可知,中序遍历中该根节点左边的序列必定在根节点的左子树中,而根节点右边的序列必定在右子树中.由此可以知道先序遍历中左子树以及右子树的起止位置. 3. 找到了左右子树前序遍历和中序遍历再用同样的方法分别构建左右子树,典型的递归思想. 代码如下: Binary

七:重建二叉树(依据先序遍历(或者后序遍历)和中序遍历重建二叉树)

对于一颗二叉树.能够依据先序遍历(或者后序遍历)和中序遍历(树中不含反复的数字)又一次还原出二叉树. 解析: 1. 先序遍历序列的第一个元素必然是根节点,能够由此获取二叉树的根节点. 2. 依据根节点,在中序遍历序列中查找该节点,由中序遍历的性质可知,中序遍历中该根节点左边的序列必然在根节点的左子树中.而根节点右边的序列必然在右子树中.由此能够知道先序遍历中左子树以及右子树的起止位置. 3. 找到了左右子树前序遍历和中序遍历再用相同的方法分别构建左右子树,典型的递归思想. 代码例如以下: Bin

由后序遍历序列和中序遍历序列确定二叉树

如何通过后序遍历序列和中序遍历序列来确定一棵二叉树?? 根据后序遍历序列最后一个结点确定根结点: 根据根结点在中序遍历序列中分割出左右两个子序列: 对左子树和右子树分别递归使用相同的方式继续分解: 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 struct node 6 { 7 char data; 8 struct node *lt, *rt; 9 }; 10 11 // 用先

由先序遍历序列和中序遍历序列确定二叉树

如何通过先序遍历序列和中序遍历序列来确定一棵二叉树? 根据先序遍历序列第一个结点确定根结点: 根据根结点在中序遍历序列中分割出左右两个子序列: 对左子树和右子树分别递归使用相同的方式继续分解: 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 struct node 6 { 7 char data; 8 struct node *lt, *rt; 9 }; 10 11 // 用先序序

二叉树系列(一):已知先序遍历序列和中序遍历序列,求后序遍历序列

首先介绍一下三种遍历顺序的操作方法: 1.先序遍历 (1)访问根结点: (2)先序遍历左子树: (3)先序遍历右子树.  2.中序遍历 (1)中序遍历左子树: (2)访问根结点: (3)中序遍历右子树. 3.后序遍历 (1)后序遍历左子树: (2)后序遍历右子树: (3)访问根结点. 知道了二叉树的三种遍历规则,只要有中序遍历序列和前后任一种遍历序列,我们就可以求出第三种遍历序列,今天我们研究的是已知先序和中序遍历序列,求后序遍历序列. 已知该二叉树的先序遍历序列为:A-B-D-E-G-C-F,

已知二叉树的先序遍历序列和中序遍历序列,求后序遍历序列。

思路: 先序序列的第一个结点为要构造二叉树的根结点,在中序序列中查找二叉树的根结点,则中序列根结点左边为根结点的左子树的中序序列,右边为根结点的右子树的中序序列.而先序序列根结点后面分别为它的左子树和右子树的先序序列.有了根结点在中序序列的位置,就知道了左子树和右子树的先序序列各自的位置.这样,就知道了根结点两个子树的序列. 然后在构造了根结点后,就可以递归调用函数来勾结根结点的左子树和右子树. 以上为二叉树的恢复. 后序遍历二叉树也是用递归即可. 代码如下: string.find()   返