二叉树构建与遍历

二叉树有三种基本的遍历方式:前序遍历、中序遍历、后序遍历。已知一棵二叉树的前序和中序遍历,求它的后序遍历,相应的,已知一棵二叉树的后序遍历和中序遍历序列你也能求出它的前序遍历。然而给定一棵二叉树的前序和后序遍历,你却不能确定其中序遍历序列,

前序遍历

遍历顺序中左右,根在首

中序遍历

遍历顺序左中右,根在中

后序遍历

遍历顺序左右中,根在后

已知前序中序求后序

#include<bits/stdc++.h>
#define intn long long
#include<iostream>
#include<cstdio>
#include<vector>
#include<string.h>
#include<cmath>
#include<stack>
#define _0for(i, a) for(int i = 0; i < (a); ++i)
#define _1for(i, a) for(int i = 1; i <=(a); ++i)
#define lowbit(x) ((x)&(-x))
#define debug(x) 
(void)(cerr << "L" << __LINE__
			<< " : " << #x << " = " 
			<< (x) << endl )
using namespace std;
string a,b;
char c[100000];
int cnt;
int l;
void ss(int l1,int r1,int l2,int r2)
{
	if(l1>r1||l2>r2)return ;
	cnt--;
	c[cnt]=b[l2]; 
	for(int i=l1;i<=r1;i++)
	{
		if(a[i]==b[l2])
		{
			int lr=r1-i;
			int ll=i-l1;	
			debug(l2+1+ll);
			ss(i+1,r1,l2+1+ll,r2);//搜右,关键代码,要理解清楚长度关系
			ss(l1,i-1,l2+1,r2-lr);//搜左, 
		}
	}
}
main(void)
{
	cin>>a>>b;//a中,b前 
	l=cnt=a.length();
	ss(0,cnt-1,0,cnt-1);
	for(int i=0;i<l;i++)
	{
		cout<<c[i];
	}
}




已知后序中序求前序

#include<bits/stdc++.h>
#define intn long long
#include<iostream>
#include<cstdio>
#include<vector>
#include<string.h>
#include<cmath>
#include<stack>
#define _0for(i, a) for(int i = 0; i < (a); ++i)
#define _1for(i, a) for(int i = 1; i <=(a); ++i)
#define lowbit(x) ((x)&(-x))
#define debug(x) 
(void)(cerr << "L" << __LINE__
			<< " : " << #x << " = " 
			<< (x) << endl )
using namespace std;
char mid[100],last[100];
void ss(int l1,int r1,int l2,int r2)
{
	int i,j,k;
	if(l1>r1||l2>r2)return ;
	char c=last[r2];
	cout<<c;
	for(int i=l1;i<=r1;i++)
	{
		if(mid[i]==c)
		{
			int cntl=i-l1;
			int cntr=r1-i;
			ss(l1,i-1,l2,r2-1-cntr);//关键代码
			ss(i+1,r1,l2+cntl,r2-1); //关键代码
		}
	}
}
main(void)
{
	cin>>mid;
	cin>>last;
	ss(0,strlen(mid)-1,0,strlen(last)-1);
}




已知前序后序求中序的可能
分析,一个二叉树中序多种情况是存在只有一个儿子的节点,只有一个儿子 的节点 才会在知道 前序后序 的情况下有不同的中序遍历,所以将题目转化成找 只有一个儿子的节点个数。

可以很容易的找出这类节点在前序后序中出现的规律。(前序中出现AB,后序中出现BA,则这个节点只有一个儿子)

每个这类节点有两种中序遍历(及儿子在左,儿子在右)根据乘法原理中序遍历数为 2^节点个数

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
char a[10002],b[10002];
int main()
{
            scanf("%s%s",&a,&b);
            int len=strlen(a),ans=1;
            for(int i=0;i<=len-2;i++)
                     for(int j=0;j<=len-1;j++)
                              if(b[j]==a[i]&&b[j-1]==a[i+1]);
            cout<<(1<<(ans+1));
            return 0; 
}
原文地址:https://www.cnblogs.com/wangqianyv/p/13359239.html