codevs 1029 遍历问题

题目描述 Description

    我们都很熟悉二叉树的前序、中序、后序遍历,在数据结构中常提出这样的问题:已知一棵二叉树的前序和中序遍历,求它的后序遍历,相应的,已知一棵二叉树的后序遍历和中序遍历序列你也能求出它的前序遍历。然而给定一棵二叉树的前序和后序,你却不能确定其中序遍历序列,考虑如下图中的几棵二叉树:

 

    所有这些二叉树都有着相同的前序遍历和后序遍历,但中序遍历却不相同。

codevs 1029 遍历问题_第1张图片
输入描述 Input Description

    输入文件共2行,第一行表示该树的前序遍历结果,第二行表示该树的后序遍历结果。输入的字符集合为{a-z},长度不超过26。

输出描述 Output Description

    输出文件只包含一个不超过长整型的整数,表示可能的中序遍历序列的总数。

样例输入 Sample Input

abc

cba

样例输出 Sample Output

4

思路:二叉树的形状由左右子树的形状数目确定,因此总的形态数目为, 左子树形态数目*右子树的形态的数目。 

当给出一个先序顺序,从第2个结点开始的所有结点组成左子树或右子树。若有n个结点,则可能的情况有,

左子树有 n - 1个结点,右子树 有 0 个结点

............. n - 2 个 .....,    ............   1  个.......

...................................................................

.................0  个,...........................n-1个结点

通过先序顺序递归的获取子树的可能状态,然后通过给出的后序顺序,判断此种形状是否合法,从而能够确定一种

树形,因此可得到一种合法的中序序列。当 得出先须的一种顺序后,检查该先须顺序中的各个结点是否出现在后序

顺序的分支中,若存在,则是一种合法的形状。 说明可以通过对这一种树形遍历得出给定的先序和后续序列,从而

确定出了一种可能的中序序列。

#include <iostream>
#include <string>
using namespace std;
bool legal(string& pre,string& post)
{
	for (int i = 0; i < pre.size(); i++)
	{
		if(post.find(pre.at(i)) == string::npos)
		{
			return false;
		}
	}
	return true;
}

int count(string pre,string post)
{
	if(pre.size() <= 1 )
	{
		return 1;
	}
	else
	{
		int t = 0;
		for (int i = pre.size() - 1; i >= 0; i--)  // 
		{
			string prel,
				   postl,
				   prer,
				   postr;
			if (pre.at(0) != post.at(post.size() - 1))  // 先序的第一个结点不等于后续的最后一个结点
			{
				continue;
			}
			// 两种顺序的左子树
			prel = pre.substr(1,i);
			postl = post.substr(0,i);
			// 两种顺序的右子树
			prer = pre.substr(i+1,pre.size()-i);
			postr = post.substr(i,post.size()-1-i);
			if (legal(prel,postl) && legal(prer,postr))
			{
				t = t + count(prel,postl) * count(prer,postr);
			}
			// 根的检查直接在这里进行了
		}
		return t;
	}
}



int main(int argc, char** argv) 
{
	string pre /*= "abc"*/,
		   post /*= "cba"*/;
	cin>>pre>>post;
	int cnt = count(pre,post);
	cout<<cnt<<endl;
	//cout<<pre.substr(1,3)<<endl;
	//cout<<pre.substr(3 + 1,pre.size()-1-3)<<endl;
	//cout<<pre.substr(6,1)<<endl;
	return 0;
}


你可能感兴趣的:(递归,二叉树)