题目给出二叉树的前序及后续遍历顺序,要求解出存在可能的二叉树数目
首先要明白为什么给出二叉树前序及中序序列就可以得到唯一的二叉树结构,而给出前序及后续遍历顺序而不能得到唯一二叉树结构问题
如二叉树 B <- A -> C
二叉树前序序列给出的是子节点与父节点的关系。如:ABC 我们可以任务BC为A的子节点
二叉树中序序列给出的是左右节点的先后关系。如:BAC 则B与C被A所阻隔,根据BC在父亲节点的左右方即可知道BC分别为左节点及右节点。
二叉树中序序列给出的是子节点与父节点的关系。如:BCA 我们可以任务BC为A的子节点
所以当给出前序序列/后续序列 + 中序序列时,能够确定父子关系及左右兄弟关系,故此二叉树结构唯一。
而当只给出前序序列 + 后续序列时,左右兄弟节点并不能很好的辨识。故不唯一。至于个数则为2的单子节点的节点个数次方,如果有3个单子节点节点,则个数为2^3 = 8种
下面介绍从前序序列 + 后续序列获得单子节点个数的一种方法:
例子:C <- B <- A -> D
此时只有B一个节点具有单子节点
给出前序序列:ABCD
给出后序序列:CBDA
前序首字母与后续尾字母相同,因为均为该树的根。
而具有单子节点的节点所分开的序列具有如下特点: 前序中及后序中出现类似BC + CB组合的,则节点B只能有一个子节点。
原因:前序中出现BC则说明有可能B为C的父节点,或者B与C为兄弟节点。而如果后序中出现CB时,则说明B可能为C的父节点,且B与C一定在同一子树上。
如果出现BC(前序中)+CB(后序中)组合,则说明B为C的父亲节点。并且B节点仅有一个子节点。
原因:若B有两个子节点,设为C,F,则先序遍历必然会出现如下结构:BC?*F (?*表示C子树进行先序遍历结构)
而后序遍历则会出现 (?*)CFB结构,此时B与C必然不会相邻。
程序源码如下:
#include <iostream>
#include <string>
using namespace std;
int getTreeNum(string preorder, string postorder)
{
int treeNum = 1;
for(int i = 1; i < preorder.length(); i++)
{
int j = postorder.length() - 2;
//找到分支点
while(preorder[i] != postorder[j]) j--;
if(preorder[i - 1] == postorder[j + 1])
treeNum *= 2;
}
return treeNum;
}
int main()
{
string preorder;
string postorder;
cin>>preorder;
cin>>postorder;
int treeNum = getTreeNum(preorder,postorder);
cout<<treeNum;
return 0;
}