您的位置:首页 > 其它

据前序遍历和中序遍历重建二叉树

2016-11-24 18:08 309 查看
这是一道面试题

由前序遍历和中序遍历重建二叉树(前序序列:1 2 3 4 5 6 - 中序序列:3 2 4 1 6 5)数据不含重复值

这个可以分析一下

前序遍历序列1 2 3 4 5 6,前序遍历规则是根--左--右

中序遍历序列3 2 4 1 6 5,中序遍历规则是左--根--右

由前序遍历可知根节点为第一个元素1,在中序遍历序列中找到1对应位置,

则1的左边就是左子树324,右边就是右子树56;

在找到前序遍历序列中从第二个位置开始往后找相同数目的节点为左子树234,剩余的就是右子树序列65,

再根据前序遍历规则可知,左子树序列里第一个就是左子树的根节点2,右子树序列里的第一个就是有右子树的根节点5,

再根据中序遍历序列可知,左子树的根节点2左边的一定是以其为根节点的左子树序列3,右边就是以其为根节点的右子树序列4,

右子树的根节点5左边的一定是以其为根节点的右子树序列6,直至序列为空,就可以完整重建二叉树了

如图:

代码


代码实现:

定义节点:

#include<iostream>
#include<stdlib.h>
using namespace std;
//定义一棵二叉树的节点
struct BTreeNode
{
int value;
BTreeNode * left;
BTreeNode* right;
};


函数实现

BTreeNode * RebuildTree(int* PreOrder,int* InOrder,int length)
{
//判断输入值是否合法
if(PreOrder == NULL || InOrder == NULL || length<=0)
{
return NULL;
}
else
{
return RebuildCore(PreOrder,PreOrder+length-1,InOrder,InOrder+length-1);

}
}

BTreeNode *RebuildCore(int *startPreOrder,int *endPreOrder,int *startInOrder,int *endInOrder)
{
//2.找到前序遍历中的根节点并创建一个节点保存节点值
BTreeNode *root = new BTreeNode();
root->value = startPreOrder[0];
root->left = NULL;
root->right = NULL;
//3.判断是否找完了此次中序遍历,若是找完了,则返回 root
if(startInOrder == endInOrder && *startInOrder == *endInOrder)
{
return root;
}
//4.根据此根节点的值在中序遍历中找此次节点的位置
int * rootIn = startInOrder;
while(*startPreOrder != *rootIn)
{
rootIn++;
}
//6.根据此根节点在中序遍历中的位置,递归还原左子树
int leftlength = rootIn-startInOrder;
if(leftlength>0)
{
root->left = RebuildCore(startPreOrder+1,startPreOrder+leftlength,startInOrder,startInOrder+leftlength-1);

}
//此处千万不要错写成 else if 因为若是这样,判断满足上面的递归条件,则进入递归还原左子树,当左子树完全被还原后,再调回这个点的时候,就不会继续执行 else if 语句了,因为上面的条件已经满足,所以右子树将没办法还原了  
if(leftlength+startInOrder < endInOrder)//左子树长度加上中序的起始位置后若仍然小于整个中序长度则说明该节点还存在右子树,所以继续递归还原右子树
{//7.根据此根节点在中序遍历中的位置,递归还原右子树
root->right = RebuildCore(startPreOrder+leftlength+1,endPreOrder,startInOrder+leftlength+1,endInOrder);
}
return root;
}


后序遍历
void PostOrder(BTreeNode *root)
{
if(root->left != NULL)
{
PostOrder(root->left);

}
if(root->right != NULL)
{
PostOrder(root->right);
}
if(root != NULL)
{
cout<<root->value<<" ";
}

}


测试代码
int main()
{
int preorder[] = {1,2,3,4,5,6};
int inorder[] = {3,2,4,1,6,5};

BTreeNode *root = RebuildTree(&preorder[0],&inorder[0],6);
PostOrder(root);//324651
cout<<endl;
system("pause");
return 0 ;

}


测试结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐