1.已知先序遍历、中序遍历、后序遍历中的任意一种方式,都无法建立起二叉树。
2.已知先序遍历和中序遍历,可以建立二叉树。
3.已知中序遍历和后序遍历,可以建立二叉树。
4.已知先序遍历和后序遍历,无法建立二叉树。
下面来看洛谷p1030
https://www.luogu.org/problemnew/show/P1030
参考题解中的思路:
首先定义两个字符串inorder,postorder存储中序和后序遍历结果,
我们从后序遍历最后一个字符找到根结点,在中序遍历中由根结点分为左子树和右子树两个部分,
根据左右子树结点的个数,在后序遍历中找到相应的左子树和右子树。
所以我们可以重新得到左右子树的中序遍历和后序遍历,可以用递归解决此问题。
#include<cstdio>
#include<iostream>
#include<string>
using namespace std;
void preorder(string inorder,string postorder){
if(!inorder.size())return;
char root=postorder[postorder.length()-1];
cout<<root;
int k=inorder.find(root);
preorder(inorder.substr(0,k),postorder.substr(0,k));//左子树
preorder(inorder.substr(k+1),postorder.substr(k,postorder.length()-k-1));//右子树
}
int main(){
string inorder,postorder;
cin>>inorder>>postorder;
preorder(inorder,postorder);
return 0;
}
对于已知先序遍历和中序遍历,求后序遍历的问题,思路是一样的。
下面附上用Python代码
class Node:
def __init__(self,data,left=None,right=None):
self.data=data
self.left=left
self.right=right
def build(preorder,inorder):
if not inorder:
return
root = Node(preorder[0])
index = inorder.find(preorder[0])
root.left=build(preorder[1:index+1],inorder[0:index])
root.right=build(preorder[index+1:],inorder[index+1:])
return root
def postorder(t):
if t==None:
return
postorder(t.left)
postorder(t.right)
print(t.data,end='')
preorder="ABDHIEJCFGKL"
inorder="HDIBEJAFCKGL"
if __name__=='__main__':
tree=build(preorder,inorder)
postorder(tree)