根据二叉树的前序遍历和中序遍历,重构出二叉树
2013-07-27 20:07
453 查看
题目:这道题目是一道面试题,先序遍历和中序遍历以数组的形式给出,要求我们根据这两个条件重构出二叉树。
下图是一棵二叉树
先序遍历:6,5,2,4,7,8
中序遍历:2,5,4,6,7,8
思路:二叉树先序遍历的定义:1,先输出根结点2,再输出左子树3,再输出右子树,因此先序遍历时,根结点总会出现在数组开头,中序遍历时,根结点可以将二叉树分为左右子树。
因此,重构二叉树的步骤可以用自顶向下的方法:
1,先在先序序列中找到根结点,
2,在中序序列中找到根结点位置,(可以将二叉树分为左子树和右子树)
3.用同样的办法构造左子树
4.用同样的办法构造右子树。
例如:
1.找到根结点6,因此左子树是2,5,4和右子树是7,8
2.找到左边根结点5,可将子二叉树分为2和4,因此左边确定。
3,找到右边根结点7,因此可确定右子树8。
根据四步走可以写出如出代码:
接下来的步骤就是进行程序测试,利用边界值等去测试程序的健壮性。
可以利用下面的二叉树去测试:
上述测试例子引自于:《剑指Offer——名企面试官精讲典型编程题》
经过测试,当输入空指针和两个序列不匹配时,原始的程序无办法处理,可以针对性处理如下:
中途发现的编译错误记录如下:点击打开链接
下图是一棵二叉树
// 6 // / \ // 5 7 // / \ \ // 2 4 8
先序遍历:6,5,2,4,7,8
中序遍历:2,5,4,6,7,8
思路:二叉树先序遍历的定义:1,先输出根结点2,再输出左子树3,再输出右子树,因此先序遍历时,根结点总会出现在数组开头,中序遍历时,根结点可以将二叉树分为左右子树。
因此,重构二叉树的步骤可以用自顶向下的方法:
1,先在先序序列中找到根结点,
2,在中序序列中找到根结点位置,(可以将二叉树分为左子树和右子树)
3.用同样的办法构造左子树
4.用同样的办法构造右子树。
例如:
1.找到根结点6,因此左子树是2,5,4和右子树是7,8
2.找到左边根结点5,可将子二叉树分为2和4,因此左边确定。
3,找到右边根结点7,因此可确定右子树8。
根据四步走可以写出如出代码:
node* Build_Tree(int* prec,int* inorder,int len) { //步骤1:新建根结点 node* root=new node(prec[0]); //步骤2:在中序遍历中找到根结点索引,分割左右子树 int SubTreeLen=0; while(SubTreeLen < len && inorder[SubTreeLen] != prec[0]) ++SubTreeLen; if(SubTreeLen > 0) { //步骤2:重建左子树,并且将根结点root的left指向左子树 root->left=Build_Tree(prec+1,inorder,SubTreeLen); } if(len-SubTreeLen-1 > 0) { //步骤2:重建右子树,并且将根结点root的left指向右子树 root->right=Build_Tree(prec+1+SubTreeLen,inorder+1+SubTreeLen,len-SubTreeLen-1); } return root; }
接下来的步骤就是进行程序测试,利用边界值等去测试程序的健壮性。
可以利用下面的二叉树去测试:
// 普通二叉树 // 1 // / \ // 2 3 // / / \ // 4 5 6 // \ / // 7 8 int preorder[length] = {1, 2, 4, 7, 3, 5, 6, 8}; int inorder[length] = {4, 7, 2, 1, 5, 3, 8, 6}; // 所有结点都没有右子结点 // 1 // / // 2 // / // 3 // / // 4 // / // 5 int preorder[length] = {1, 2, 3, 4, 5}; int inorder[length] = {5, 4, 3, 2, 1}; // 所有结点都没有左子结点 // 1 // \ // 2 // \ // 3 // \ // 4 // \ // 5 int preorder[length] = {1, 2, 3, 4, 5}; int inorder[length] = {1, 2, 3, 4, 5}; // 树中只有一个结点 int preorder[length] = {1}; int inorder[length] = {1}; // 完全二叉树 // 1 // / \ // 2 3 // / \ / \ // 4 5 6 7 int preorder[length] = {1, 2, 4, 5, 3, 6, 7}; int inorder[length] = {4, 2, 5, 1, 6, 3, 7}; // 输入空指针 // 输入的两个序列不匹配 int preorder[length] = {1, 2, 4, 5, 3, 6, 7}; int inorder[length] = {4, 2, 8, 1, 6, 3, 7};
上述测试例子引自于:《剑指Offer——名企面试官精讲典型编程题》
经过测试,当输入空指针和两个序列不匹配时,原始的程序无办法处理,可以针对性处理如下:
#include<iostream> #include <exception> using std::cout; using std::endl; struct node { int value; node* left; node* right; node(int v):value(v),left(NULL),right(NULL){} }; node* Build_Tree(int* prec,int* inorder,int len) { if(!prec || !inorder || len <=0 ) { cout<<"Empty Input!"<<endl; exit(1);//暴力关机 } //步骤1:新建根结点 node* root=new node(prec[0]); //步骤2:在中序遍历中找到根结点索引,分割左右子树 int SubTreeLen=0; while(SubTreeLen < len && inorder[SubTreeLen] != prec[0]) ++SubTreeLen; if(SubTreeLen == len)//越界了,说明两个数组无法构造出二叉树 { cout<<"Wrong Input!"<<endl; exit(1);//暴力关机 } if(SubTreeLen > 0) { //步骤2:重建左子树,并且将根结点root的left指向左子树 root->left=Build_Tree(prec+1,inorder,SubTreeLen); } if(len-SubTreeLen-1 > 0) { //步骤2:重建右子树,并且将根结点root的left指向右子树 root->right=Build_Tree(prec+1+SubTreeLen,inorder+1+SubTreeLen,len-SubTreeLen-1); } return root; } void prec_tree_walk(node* z) { if(!z) return ; cout<<z->value<<' '; prec_tree_walk(z->left); prec_tree_walk(z->right); } void inorder_tree_walk(node* z) { if(!z) return ; inorder_tree_walk(z->left); cout<<z->value<<' '; inorder_tree_walk(z->right); } int main() { int prec[] = {1, 2, 4, 7, 3, 5, 6, 8}; int Inorder[] = {4, 7, 2, 1, 5, 3, 8, 6}; int len=sizeof(prec)/sizeof(prec[0]); node* root=Build_Tree(prec,Inorder,len); prec_tree_walk(root); cout<<endl; inorder_tree_walk(root); return 0; }
中途发现的编译错误记录如下:点击打开链接
相关文章推荐
- 二叉树根据前序遍历和中序遍历重构确定唯一二叉树
- 根据二叉树的前序遍历和中序遍历,重构二叉树
- 根据前序遍历和中序遍历重构二叉树
- 由前序遍历和中序遍历重构二叉树
- 7-9 还原二叉树(25 point(s))(根据前序遍历和中序遍历建树)
- 根据前序遍历序列和中序遍历序列创建二叉树
- 算法面试:根据前序遍历结果序列和中序遍历结果序列重构二叉树
- POJ 2255Tree Recovery 二叉树重建(根据前序遍历和中序遍历写出后序遍历)
- C++ 根据前序遍历序列和中序遍历序列可以构造唯一的二叉树
- 3.9已知二叉树的 前序遍历和中序遍历的结果,重构出原二叉树
- 刷题之路----根据前序遍历和中序遍历或者后序遍历和中序遍历重建二叉树
- 从二叉树的前序遍历序列和中序遍历序列重构出二叉树
- 根据二叉树的前序遍历和中序遍历的结果重建出该二叉树
- 剑指Offer_06 根据前序遍历和中序遍历序列 重建二叉树
- 027根据前序遍历和中序遍历,重建二叉树(keep it up)
- 根据二叉树的中序和后序遍历,求前序遍历
- 根据前序遍历序列和中序遍历序列构造二叉树
- 根据前序遍历和中序遍历重建二叉树
- 根据前序遍历和中序遍历,构造二叉树
- 根据二叉树的前序遍历和中序遍历的结果,重建二叉树