第三部分 数据结构 --树-1366:二叉树输出(btout)

【题目描述】
树的凹入表示法主要用于树的屏幕或打印输出,其表示的基本思想是兄弟间等长,一个结点的长度要不小于其子结点的长度。二叉树也可以这样表示,假设叶结点的长度为1,一个非叶结点的长度等于它的左右子树的长度之和。

一棵二叉树的一个结点用一个字母表示(无重复),输出时从根结点开始:

每行输出若干个结点字符(相同字符的个数等于该结点长度),如果该结点有左子树就递归输出左子树;如果该结点有右子树就递归输出右子树。

假定一棵二叉树一个结点用一个字符描述,现在给出先序和中序遍历的字符串,用树的凹入表示法输出该二叉树。

【输入】
两行,每行是由字母组成的字符串(一行的每个字符都是唯一的),分别表示二叉树的先序遍历和中序遍历的序列。

【输出】
行数等于该树的结点数,每行的字母相同。

【输入样例】
ABCDEFG
CBDAFEG

【输出样例】
AAAA
BB
C
D
EE
F
G
————————————————
思路:按先序遍历顺序找,则找的结点和b中的每个字符是一一对应的关系,在中序遍历查找这个字符,则它就是根,它在b的左部分即为左子树,右边则为右子数部分。

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 100001

using namespace std;
char a[N],b[N];
int c[N],lena,lenb;
int f(int l1,int r1,int l2,int r2)
{
    if(l1 == r1)//叶子结点长度为1
    {
        c[l1] = 1;
        return c[l1];
    }
    int i;
    for(i = l2;i <= r2;i++)
        if(a[l1] == b[i])
            break;
    if(i < r2)
        c[l1] += f(r1-(r2-(i+1)),r1,i+1,r2);//递归求出右儿子长度 
    if(i > l2)
        c[l1] += f(l1+1,l1+i-l2,l2,i-1);//递归求出左儿子长度 
    return c[l1];
}
int main()
{
    cin >> a >> b;//a先序和b中序
    lena = strlen(a);
    lenb = strlen(b);
    f(0,lena-1,0,lenb-1);
    for(int i = 0;i < lena;i++)
    {
        for(int j = 1;j <= c[i];j++)
            cout << a[i];//先序遍历顺序输出
        cout << endl;
    }
}


程序二

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int i = -1,a[200];
string s1,s2;
int tree(int l,int r)
{
	int tot = 0,k = ++i; //a[i]表示结点i的长度 
	int m = s2.find(s1[k]);//中序遍历中查找这个字符,它就是根他在s2的左边部分就是左子树 右边是右子树  
	if(m > l) tot += tree(l,m-1);//递归求左子树长度 
	if(m < r) tot += tree(m+1,r);//递归求右子树长度,再推出根的长度 
	if(l == r) tot = 1;//叶子结点长度为1 
	a[s1[k]] = tot;//记录答案 
	return tot; 
	
 } 
 int main(){
 	cin >> s1 ;
 	cin >> s2;
 	tree(0,s1.size()-1);//两个字符串长度一样取一个就可以了 
 	for(int i = 0 ; i < s1.size();i++)
 	{
 		for(int j = 1; j <= a[s1[i]];++j)
 		putchar(s1[i]);//先序遍历输出即可 
 		putchar('\n');
	 }
 	return 0;
 } 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章