摘要
根據前序遍歷和中序遍歷求該二叉樹按層遍歷的序列。
import java.util.Arrays;
import java.util.Iterator;
import java.util.Scanner;
import java.util.TreeMap;
/************************************
* *
* @Modification 優化程序 *
* *
* @version 1.0.1 *
* *
* @author 何明勝 *
* *
* @Date 2017-04-02 12:38:04 *
* *
************************************/
public class FormerAndInTraToTree {
int former_traversal[];//前序遍歷數組
int former_cursor = 0;//前序遍歷數組遊標
int in_traversal[];//中序遍歷數組
int []result;//結果存儲數組
TreeMap<Integer, Integer> tree_map = new TreeMap<Integer, Integer>();//結果在樹中的下標
//初始化函數
public void init(){
@SuppressWarnings("resource")
Scanner scanner = new Scanner(System.in);
int len = scanner.nextInt();//樹中元素的個數
//初始化
former_traversal = new int[len];
in_traversal = new int[len];
result = new int[len];
//讀入前序遍歷
for(int i=0;i<len;i++){
former_traversal[i] = scanner.nextInt();
}
//讀入中序遍歷
for(int j=0;j<len;j++){
in_traversal[j] = scanner.nextInt();
}
}
//開始執行函數
public void start() {
/*遞歸調用入口
//第一個參數爲當前根節點的下標,初始化爲樹的根節點1
//第二個參數爲當前根節點在中序遍歷中的位置下標
//第三個參數爲當前中序數組
//前序遍歷順序:根節點->左子節點->右子節點 中序遍歷:左子節點->根節點->右子節點
//前序遍歷是對根節點的遍歷,根據前序遍歷遊標former_cursor的值遍歷前序遍歷數組former_traversal的所有根節點
//確定每個根節點在中序遍歷數組中的位置,//賦值給結果數組,下標爲當前root//
//在該數組中其元素左邊的元素爲其左字樹,右邊爲其右子樹
//對其子樹繼續遞歸,//左子樹根節點下標爲當前root*2,右子樹根節點下標爲當前root*2+1//
//直到其左邊或者右邊只有一個元素時,則爲其左子節點和右子節點
//賦值給結果數組,//左子節點下標爲當前root*2,右子節點下標爲root*2+1//
*/
myRecursive(1,inThisChild(in_traversal), in_traversal);
//打印最終結果。tree自動排序,跟key中存儲的下標值,按序打印結果
for(Iterator<Integer> iterator = tree_map.keySet().iterator();iterator.hasNext();){
int tree_num = tree_map.get(iterator.next());
System.out.print(result[tree_num]+ " ");
}
}
//遞歸調用函數
public void myRecursive(int root, int root_in_tra, int in_tra[]){
//賦值當前根節點
tree_map.put(root, former_cursor);//當前節點對應的下標爲key,當前節點在數組中的下標爲value
result[former_cursor++] = in_tra[root_in_tra];//當前節點賦值給結果數組
//中序遍歷當前節點已賦值,前序中游標former_cursor加1
if(1 == root_in_tra){//當前根節點爲1,左邊只有一個元素,爲其左子節點
tree_map.put(root*2, former_cursor);//保存當前根節點的下標
result[former_cursor++] = in_tra[0];//賦值給當前根節點左子節點
//中序遍歷當前節點已賦值,前序中游標former_cursor加1
}
else if(0 != root_in_tra){//排除當前根節點在數組最左邊的情況
//截取當前根節點左邊的元素(左子樹)爲新數組
int left_child[] = Arrays.copyOfRange(in_tra, 0, root_in_tra);
//判斷當前根節點是否在左子樹中
if(inThisChild(left_child) > -1){
myRecursive(root*2, inThisChild(left_child), left_child);
}
}
if(1 == (in_tra.length-1 -root_in_tra)){//當前根節點右邊只有一個元素,爲其右子節點
tree_map.put(root*2+1, former_cursor);
result[former_cursor++] = in_tra[root_in_tra+1];//賦值給右子節點
//中序遍歷當前節點已賦值,前序中游標former_cursor加1
}
else if(0 != (in_tra.length-1 -root_in_tra)){//排除當前根節點在數組最右邊的情況
//截取當前根節點右邊的元素(右子樹)爲新數組
int right_child[] = Arrays.copyOfRange(in_tra, root_in_tra+1, in_tra.length);
//判斷當前根節點是否在右子樹中
if(inThisChild(right_child) > -1){
myRecursive(root*2+1, inThisChild(right_child), right_child);
}
}
}
//判斷當前遊標對應的根節點是否在傳入的子樹中
public int inThisChild(int []array){
for(int i=0;i<array.length;i++){
if(array[i] == former_traversal[former_cursor])
return i;//若在,返回其在該子樹(數組)中的下標
}
return -1;//若不在,返回-1
}
public static void main(String[] args) {
FormerAndInTraToTree test = new FormerAndInTraToTree();//實例化
test.init();//初始化
test.start();//開始執行
}
}