題目:
寫一程式建立一棵binary search tree, 同時寫recursise與nonrecursive 版method (或function) 去traverse這棵binary search tree, 將它的preorder, inorder, 與 postorder列印出來.請參考課本第七章所附之建立binary search tree與 binary tree traversal程式, 假設每個binary search tree node存一個整數, 而binary search tree的preorder, inorder, postorder是以visit node時以輸出該node所存之整數順序代表。
程式架構:
使用者輸入要輸入幾個數字,以size記錄,產生兩個Array,大小為2^(size)。
numTree為儲存數字,storage為儲存是否有存入數字。
用一個while迴圈讓使用者輸入,
第一個數字放在root(index=1)。
第二個以後,
若較小或等於放在left child。(index*2)
若較大放在right child。(index*2+1)
輸入滿15(size)個數就跳出迴圈。
印tree
第一行空7格(size/2),並逐行遞減,以變數tab記錄。
每印到2^n-1的數則換行,以變數chLine記錄。
countPrNum則紀錄印出幾個node。
迴圈以i=1開始,到array.length結束。
有node印出數字。
沒有node印x。
Traversal(Recursion)
Inorder
catch 三個值,storage[],numTree[],curIndex=1
如果curIndex在範圍內,
則作以下判斷,
如果沒有left child(curIndex*2)和right child(curIndex*2+1)
若有node,印出值。
如果有則,
呼叫Inorder(storage[],numTree[],curIndex*2)
印出目前的值。
呼叫Inorder(storage[],numTree[],curIndex*2+1)
如果不在範圍內
若有node,印出來。
Preorder和Postorder大致上一樣。
只是Preorder是
System.out.print(numTree[curIndex]+" "); //node
preorder(storage,numTree,curIndex*2);//left child
preorder(storage,numTree,curIndex*2+1);//right child
Postorder是,
preorder(storage,numTree,curIndex*2);//left child
preorder(storage,numTree,curIndex*2+1);//right child
System.out.print(numTree[curIndex]+" "); //node
Traversal(Non Recursion)
Inorder
用另一個boolean array紀錄storage裡的值,stoInorder。
用一個stack紀錄存過的index。
用IfChild紀錄目前的index。
while loop(prCount!=size)
如果有left child
將自己push進去。
將left child push進去。
如果沒有left child
如果有node,印出來。
將自己的位置設成false。
將prCount++。
檢查是否有right child,
有的話push進去。
Preorder
用另一個boolean array紀錄storage裡的值,stoPreorder。
用一個stack紀錄存過的index。
用IfChild紀錄目前的index。
while loop(prCount!=size)
如果沒有left child也沒有right child,
若有node,印出來,prCount++,位置設成false。
若有的話
先將自己印出來。
prCount++。
檢查right child,有的話push
檢查left child,有的話push
Postorder
用另一個boolean array紀錄storage裡的值,stoPreorder。
用一個stack紀錄存過的index。
用IfChild紀錄目前的index。
while loop(prCount!=size)
如果沒有left child也沒有right child,
若有node,印出來,prCount++,位置設成false。
若有的話
push自己。
檢查right child,push right child。
檢查left child,有的話push。
討論:
建tree的想法,因為對array還是比較熟一些,所以先用array來寫,結果弄到後面好像也沒比較輕鬆,如果其他作業也完成的話,會來試看看linked list的部分。
一開始的數放root,其餘的數,小的放左邊,大的放右邊,以此類推。
index=0的位置則放棄掉,這樣才會有index*2=left child,index*2+1=right child的效果。
recursive的方法很直觀,即是以Traversal的順序來印出。non recursive則是每個Order略有不同,一部分是寫一寫想到更好的方法,因而改掉的,以及要注意印出的順序,push的順序會有所不同,例如:若是LRV,push順序就是 node,right child,left child。
執行畫面:
How many number do you want?15
Please input number:
20 16 11 19 25 61 5 8 97 3 12 66 18 17 30
How many number do you want?15
Please input number:
85 13 73 87 61 51 22 44 85 74 16 79 74 92 96
![]()
How many number do you want?15
Please input number:
56 36 75 100 9 44 41 24 15 37 64 71 91 6 2
![]()
程式碼:
Recursive
import java.util.Scanner;
public class BinaryTree {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
System.out.print("How many number do you want?");
int size=input.nextInt();
int numTree []=new int[(int)Math.pow(2, size)];
boolean storage []=new boolean[(int)Math.pow(2, size)];
System.out.println("Please input number:");
//input number
for(int i=0;i<size;i++){
int num=input.nextInt();
for(int j=1;j<numTree.length;){
int temp=j;
if(!storage[j]){
numTree[j]=num;
storage[j]=true;
break;
}
else if (storage[j]){
if(num<numTree[j])
j*=2;
else if(num>numTree[j])
j=j*2+1;
else
j*=2;
}
}
}
//print tree
int chLine=1;
int tab=15;
int countPrNum=0;
boolean space=true;
int i=1;
for(;i<numTree.length;i++){
if(space){
for(int j=0;j<tab;j++){
System.out.print(" ");
}
space=false;
}
if(storage[i]){
System.out.print(numTree[i]+" ");
countPrNum++;
}
else
System.out.print("x");
if(i==(int)Math.pow(2,chLine)-1){
System.out.println();
chLine++;
tab--;
space=true;
if(countPrNum==size)
break;
}
}
System.out.print("\n");
System.out.print("Inorder:");
inorder (storage,numTree,1);
System.out.print("\n");
System.out.print("Preorder:");
preorder (storage,numTree,1);
System.out.print("\n");
System.out.print("Postorder:");
postorder (storage,numTree,1);
}
static void inorder (boolean storage[],int numTree[],int curIndex){
if(curIndex*2+1<storage.length){
if(storage[curIndex*2]==false&&storage[curIndex*2+1]==false){
if(storage[curIndex])
System.out.print(numTree[curIndex]+" ");
}
else {
inorder(storage,numTree,curIndex*2);
System.out.print(numTree[curIndex]+" ");
inorder(storage,numTree,curIndex*2+1);
}
}
else{
if(storage[curIndex])
System.out.print(numTree[curIndex]+" ");
}
}
static void preorder (boolean storage[],int numTree[],int curIndex){
if(curIndex*2+1<storage.length){
if(storage[curIndex*2]==false&&storage[curIndex*2+1]==false){
if(storage[curIndex])
System.out.print(numTree[curIndex]+" ");
}
else {
System.out.print(numTree[curIndex]+" ");
preorder(storage,numTree,curIndex*2);
preorder(storage,numTree,curIndex*2+1);
}
}
else{
if(storage[curIndex])
System.out.print(numTree[curIndex]+" ");
}
}
static void postorder (boolean storage[],int numTree[],int curIndex){
if(curIndex*2+1<storage.length){
if(storage[curIndex*2]==false&&storage[curIndex*2+1]==false){
if(storage[curIndex])
System.out.print(numTree[curIndex]+" ");
}
else {
postorder(storage,numTree,curIndex*2);
postorder(storage,numTree,curIndex*2+1);
System.out.print(numTree[curIndex]+" ");
}
}
else{
if(storage[curIndex])
System.out.print(numTree[curIndex]+" ");
}
}
}
Non Recursive
import java.util.Scanner;
import java.util.Stack;
public class BinaryTree_NR {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
System.out.print("How many number do you want?");
int size=input.nextInt();
int numTree []=new int[(int)Math.pow(2, size)];
boolean storage []=new boolean[(int)Math.pow(2, size+1)];
System.out.println("Please input number:");
//input number
for(int i=0;i<size;i++){
int num=input.nextInt();
for(int j=1;j<numTree.length;){
int temp=j;
if(!storage[j]){
numTree[j]=num;
storage[j]=true;
break;
}
else if (storage[j]){
if(num<numTree[j])
j*=2;
else if(num>numTree[j])
j=j*2+1;
else
j*=2;
}
}
}
//print tree
int chLine=1;
int tab=15;
int countPrNum=0;
boolean space=true;
int i=1;
for(;i<numTree.length;i++){
if(space){
for(int j=0;j<tab;j++){
System.out.print(" ");
}
space=false;
}
if(storage[i]){
System.out.print(numTree[i]+" ");
countPrNum++;
}
else
System.out.print("x");
if(i==(int)Math.pow(2,chLine)-1){
System.out.println();
chLine++;
tab--;
space=true;
if(countPrNum==size)
break;
}
}
System.out.print("\n");
System.out.print("Inorder:");
inorder (storage,numTree,size,1);
System.out.print("\n");
System.out.print("Preorder:");
preorder (storage,numTree,size,1);
System.out.print("\n");
System.out.print("Postorder:");
postorder (storage,numTree,size,1);
}
//LVR
static void inorder (boolean storage[],int numTree[],int size,int curIndex){
Stack <Integer> inorder=new Stack<Integer>();
boolean stoInorder []=new boolean[storage.length];
for(int i=1;i<storage.length;i++){
stoInorder[i]=storage[i];
}
inorder.push(curIndex);
int prCount=0;
int lfChild;
while(true){
if(prCount==size)
break;
lfChild=inorder.pop();
if(stoInorder[lfChild*2]){
inorder.push(lfChild);
inorder.push(lfChild*2);
continue;
}
else{
if(stoInorder[lfChild]){
System.out.print(numTree[lfChild]+" ");
stoInorder[lfChild]=false;
prCount++;
if(stoInorder[lfChild*2+1])
inorder.push(lfChild*2+1);
}
}
}
}
//VLR
static void preorder (boolean storage[],int numTree[],int size,int curIndex){
Stack <Integer> preorder=new Stack<Integer>();
boolean stoPreorder []=new boolean[storage.length];
for(int i=1;i<storage.length;i++){
stoPreorder[i]=storage[i];
}
preorder.push(curIndex);
int prCount=0;
int lfChild;
while(true){
if(prCount==size)
break;
lfChild=preorder.pop();
if(stoPreorder[lfChild*2]==false&&stoPreorder[lfChild*2+1]==false){
System.out.print(numTree[lfChild]+" ");
stoPreorder[lfChild]=false;
prCount++;
continue;
}
else{
System.out.print(numTree[lfChild]+" ");
prCount++;
if(stoPreorder[lfChild*2+1])
preorder.push(lfChild*2+1);
if(stoPreorder[lfChild*2])
preorder.push(lfChild*2);
}
}
}
//RVL
static void postorder (boolean storage[],int numTree[],int size,int curIndex){
Stack <Integer> postorder=new Stack<Integer>();
boolean stoPostorder []=new boolean[storage.length];
for(int i=1;i<storage.length;i++){
stoPostorder[i]=storage[i];
}
postorder.push(curIndex);
int prCount=0;
int lfChild;
while(true){
if(prCount==size)
break;
lfChild=postorder.pop();
if(stoPostorder[lfChild*2]==false&&stoPostorder[lfChild*2+1]==false){
System.out.print(numTree[lfChild]+" ");
stoPostorder[lfChild]=false;
prCount++;
continue;
}
else{
postorder.push(lfChild);
if(stoPostorder[lfChild*2+1]){
postorder.push(lfChild*2+1);
}
if(stoPostorder[lfChild*2]){
postorder.push(lfChild*2);
}
}
}
}
}