1. 程式人生 > 其它 >【DFS】新二叉樹

【DFS】新二叉樹

題目描述

輸入一串二叉樹,用遍歷前序打出。

輸入格式

第一行為二叉樹的節點數n(n≤26)。

後面n行,每一個字母為節點,後兩個字母分別為其左右兒子,空節點用*表示。

保證:讀入的第一個結點就是根結點。

輸出格式

前序排列的二叉樹。

樣例輸入

6
abc
bdi
cj*
d**
i**
j**

樣例輸出

abdicj

分析

題最終目的是輸出二叉樹的前序遍歷結果。首先回顧下前序遍歷的形式:

  1. 遍歷根節點
  2. 前序遍歷左子樹
  3. 前序遍歷右子樹

從描述中能發現很明顯的遞迴結構,大致結構虛擬碼:

void frontOrder(root){
    //遍歷根節點
    cout<<root.val<<" ";//輸出根節點資訊
    //前序遍歷左子樹
    frontOrder(root.leftChild);
    //前序遍歷右子樹
    frontOrder(root.rightChild);
}

繼續分析,現在欠缺的是二叉樹的建立。觀察輸入格式,它是以小寫字母代表各結點,用'*'表示空節點。

如果用陣列儲存結點資訊,為了方便字母與結點位置的對應我們可以利用ASCII碼值的差值與連續性,將小寫字母減去'a'從而對應上數字0 ~ 25。正好用這些數字與陣列下標產生對映。

int num=c-'a';//小寫字母對應上 0 ~ 25

過程中需要注意空節點的處理,以及根節點的資訊記錄。

參考程式碼

#include <iostream>
using namespace std;
int n;
struct node{
	int li,ri;
}dot[30];

void dfs(int x){
	if(x==-1) return ;
	//前序遍歷 根 左 右
	//遍歷根節點
	cout<<char(x+'a');//將0~25再轉成a~z 
	//遍歷左子樹
	dfs(dot[x].li);
	
	//遍歷右子樹
	dfs(dot[x].ri);
}
int main(){
	char a,l,r;
	int root;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a>>l>>r;//輸入節點關係
		//為了進行節點的快速處理,將'a'~'z'轉成對應0~25  '*'轉成-1
		int idx=a-'a';
		if(i==1) root=idx;//記錄根節點
		if(l=='*')
			dot[idx].li=-1;
		else
			dot[idx].li=l-'a';
		if(r=='*')
			dot[idx].ri=-1;
		else
			dot[idx].ri=r-'a';
	}
	dfs(root);
	return 0;
}
不積矽步,無以至千里。