闲谈二叉树之由前序序列与中序序列还原二叉树
在数据结构二叉树的学习中,我们首先熟悉了二叉树的四种遍历输出序列,分别为前序遍历,中序遍历,后序遍历以及层次遍历。那么当我们知道了前序遍历序列与中序遍历序列,我们应该如何得到原来的二叉树?
先看一下例题吧:
前序遍历:ABDHIEJKCFLMGNO
中序遍历:HDIBJEKALFMCNGO
我们需要还原这棵二叉树
基本思路:
1.首先我们可以从前序遍历的特点得出:第一个元素为根节点,而在中序遍历中根节点左边为左子树,右边为右子树。
2.在每一个子树中,同理可以得到根节点。
由此我们可以整理出大概的方法,利用递归,我们可以将复杂问题简单化。
代码如下:
1.这是我们的通过前序遍历与中序遍历还原二叉树的构造函数
linkedBinaryTree::linkedBinaryTree(string preOr, string inOr)
{
int treeLength = preOr.length();
treeSize = treeLength;
root = getTree(preOr,0,treeLength,inOr,0,treeLength);
}
2.由于用到递归,我们可以写一个非成员函数来实现
binaryTreeNode* getTree(string preOr, int preOrBin, int preOrEnd, string inOr, int inOrBin,int inOrEnd)
{
if(preOrBin>=preOrEnd||inOrBin>=inOrEnd){
return NULL;
}else{
char preChar[preOrEnd-preOrBin];
for(int i=preOrBin;i<preOrEnd;i++)
preChar[i-preOrBin] = preOr.at(i);
char inChar[inOrEnd-inOrBin];
for(int i=inOrBin;i<inOrEnd-inOrBin;i++)
inChar[i-inOrBin] = inOr.at(i);
binaryTreeNode *root = new binaryTreeNode(preChar[0]);
for(int i=0;i<inOrEnd-inOrBin;i++){
if(inChar[i]==root->element){
root->leftChild = getTree(preOr,preOrBin+1,preOrBin-inOrBin+i+1,inOr,inOrBin,i);
root->rightChild = getTree(preOr,preOrEnd-inOrEnd+i+1,preOrEnd,inOr,i+1,inOrEnd);
}
}
return root;
}
}
代码为了比较全面,可能在结构上有点复杂,代码核心部分只有递归的部分:
for(int i=0;i<inOrEnd-inOrBin;i++){
if(inChar[i]==root->element){
root->leftChild = getTree(preOr,preOrBin+1,preOrBin-inOrBin+i+1,inOr,inOrBin,i);
root->rightChild = getTree(preOr,preOrEnd-inOrEnd+i+1,preOrEnd,inOr,i+1,inOrEnd);
}
}