FBI樹   (建立)遍歷二叉樹

題目:我們可以把由“0”和“1”組成的字符串分爲三類:全“0”串稱爲B串,全“1”串稱爲I串,既含“0”又含“1”的串則稱爲F串。
  FBI樹是一種二叉樹,它的結點類型也包括F結點,B結點和I結點三種。由一個長度爲2N的“01”串S可以構造出一棵FBI樹T,遞歸的構造方法如下:
  1)T的根結點爲R,其類型與串S的類型相同;
  2)若串S的長度大於1,將串S從中間分開,分爲等長的左右子串S1和S2;由左子串S1構造R的左子樹T1,由右子串S2構造R的右子樹T2。
  現在給定一個長度爲2N的“01”串,請用上述構造方法構造出一棵FBI樹,並輸出它的後序遍歷序列。
輸入格式
  第一行是一個整數N(0 <= N <= 10),第二行是一個長度爲2N的“01”串。
輸出格式
  包括一行,這一行只包含一個字符串,即FBI樹的後序遍歷序列。
樣例輸入
3
10001011
樣例輸出
IBFBBBFIBFIIIFF


方法一)建立二叉樹,然後遍歷
#include<iostream> 
#include<cstdlib> 
using namespace std; 
int length;
char s[1<<10];
typedef struct Node{
	char node;
	struct Node *left;
	struct Node *right;
}tNode;

char FBI(int begin,int end)
{
	bool zero = false;
	bool one = false;
	for(int i = begin;i <= end;i ++)
	{
		if(s[i] == '0')
		{
			zero = true;
		}
		if(s[i] == '1')
		{
			one = true;
		}
		if(zero && one)
		break;
	}
	if(zero && !one)
	{
		return 'B';
	}
	if(one && !zero)
	{
		return 'I';
	}
	if(zero && one)
	{
		return 'F';
	}
	
}

tNode* build(int begin,int end)
{

    tNode*tree = (tNode*)malloc(sizeof(tNode));
	tree->node = FBI(begin,end);
	tree->left = tree->right = NULL;
	if(begin != end)	
	{
		tree->left = build(begin,(begin+end)/2);
	    tree->right = build((begin+end)/2 + 1,end);
	}
	
	return tree;
}

void preVist(tNode *tree)
{
	if(tree)
	{
		preVist(tree->left);
	    preVist(tree->right);
	    cout << tree->node;
	}
	
}

int main()
{
	int n;
	length = 1;
	cin >> n;
	cin >> s;
	while(n --)
	{
		length *= 2;
	}
	length --;
	tNode *Tree ;
	Tree = build(0,length);
	preVist(Tree);
	cout << endl;
	free(Tree);
	return 0;
}
之前在建立二叉樹的時候,結束遞歸的條件是這樣寫的:
tNode* build(int begin,int end)
{

    tNode*tree = (tNode*)malloc(sizeof(tNode));
	tree->node = FBI(begin,end);
	tree->left = tree->right = NULL;
	if(begin == end)	
	tree = NULL;
	else
	{
		tree->left = build(begin,(begin+end)/2);
	    tree->right = build((begin+end)/2 + 1,end);
	}
	
	return tree;
}
傻傻地清空了葉子結點,遍歷出來的結果就不正確了。

方法二)不需要建立二叉樹,在遍歷過程中因爲先判斷左右子樹並輸出,最後根據左右子樹來判斷結點並輸出,所以是後序遍歷。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char str[1025];
char put[3] = {'B', 'I' ,'F'};

int srch(int start, int end)
{
	int i, j;
	if(start == end){
    printf("%c", put[str[start] - '0']);
	return str[start] - '0';
	}
	i = srch(start, (start + end) / 2);//左子樹 
	j = srch((start + end) / 2 + 1, end);//右子樹 
	if(i == j){ //如果左右子樹相同 
		printf("%c", put[i]);
		return i;
	}else{//左右子樹不相同 
		printf("%c", 'F');
		return 2;
	}
}

int main()
{
	int n;
	scanf("%d\n", &n);
	scanf("%s", str);
	srch(0, strlen(str) - 1);
	printf("\n");
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章