第三部分 數據結構 --樹-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;
 } 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章