您的位置:首页 > Web前端

【剑指offer】第六题-重建二叉树

2017-06-10 12:46 369 查看
问题描述:

输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并输出其头节点。

问题分析:

在二叉树前序遍历中,第一个数字总是树的根节点的值。但在中序遍历中根节点则在中间,且左子树的节点的值在根节点的左边,右子树的节点的值在根节点的右边。如下图所示:



根据二叉树前序遍历和中序遍历的过程,我们可以:

1、先从前序遍历序列中找第一个节点构造根节点;

2、从中序遍历序列中找到根节点,则根节点左边的数据就是该根节点左子树的节点的值,根节点右边的数据就是该根节点右子树的节点的值;

3、求出左子树的长度,递归的构建左子树;

4、从根节点后一个节点开始来构建右子树。

代码实现如下:

#include<iostream>
using namespace std;
struct BinaryTreeNode
{
int value;
BinaryTreeNode * left;
BinaryTreeNode * right;
BinaryTreeNode(int v=int())
:value(v)
,left(NULL)
,right(NULL)
{}
};
class ReBulidBinaryTree
{
public:
typedef BinaryTreeNode Node;
Node * ReBulid(int *PrevStart, int * PrevEnd, int * InStart, int *InEnd)
{
Node * root = new Node(PrevStart[0]);
root->left = root->right = NULL;
if (PrevStart == PrevEnd && InStart == InEnd)
{
return root;
}
//中序遍历序列中找根节点
int * rootInorder = InStart;
while (rootInorder <=InEnd && *rootInorder != PrevStart[0])
{
rootInorder++;
}
if (rootInorder > InEnd)//没有找到根节点
{
cout<<"input error"<<endl;
return NULL;
}
int LeftLen = rootInorder - InStart;
if (LeftLen > 0)
{
root->left = ReBulid(PrevStart + 1, PrevStart + LeftLen, InStart, rootInorder - 1);
}
if (rootInorder < InEnd)
{
root->right = ReBulid(PrevStart + LeftLen + 1, PrevEnd, rootInorder + 1, InEnd);
}
return root;
}
Node * ReBulidTree(int* PrevOrder, int *InOrder, int len)
{
if (PrevOrder == NULL || InOrder == NULL || len <= 0)
{
return NULL;
}
_root= ReBulid(PrevOrder, PrevOrder + len - 1, InOrder, InOrder + len - 1);
}
void PostOrder()//后序遍历二叉树
{
PostOrder(_root);
}
void PostOrder(Node *root)//后序遍历二叉树
{
if (root)
{
PostOrder(root->left);
PostOrder(root->right);
cout << root->value << " ";
}
}
private:
Node * _root;
};

int main()
{
int PrevOrder[] = { 1,2,4,7,3,5,6,8 };
int InOrder[] = { 4,7,2,1,5,3,8,6 };
int PrevLen = sizeof(PrevOrder) / sizeof(PrevOrder[0]);
int InLen = sizeof(InOrder) / sizeof(InOrder[0]);
if (PrevLen != InLen)
{
cout << "input error!" << endl;
return -1;
}
ReBulidBinaryTree rb;
rb.ReBulidTree(PrevOrder, InOrder, PrevLen);
rb.PostOrder();
cout << endl;
system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息