標籤:
前一段時間,學習資料結構的各種演算法,概念不難理解,只是被C++的指標給弄的犯糊塗,於是用java,web,javascript,分別去實現資料結構的各種演算法。
二叉樹的遍曆,本分享只是以二叉樹中的先序遍曆為例進行說明,中序遍曆和後序遍曆,以此類推!
二叉樹遞迴與非遞迴遍曆的區別,雖然遞迴遍曆,跟容易讀懂,代碼量少,運算快,但是卻容易出現溢出的問題,所以所以非遞迴遍曆,在處理千萬級的運算量時會先的很有用處。
二叉樹的先序遍曆:先訪問根節點,再訪問先後訪問左右節點。
二叉樹的遞迴遍曆之java:
package rest;//構造節點,產生一顆樹 class Node{ Node(String Letter){ //建構函式 value=Letter; } public Node left; //左節點 public Node right; //右節點 public String value; }public class Test { public static void main(String[] args) { //以下是構建中的二叉樹,從根節點起一層一層的構建 Node root = new Node("A"); Node first = new Node("B"); Node second = new Node("C"); Node third = new Node("D"); Node foth = new Node("E"); Node fifth = new Node("F"); Node sixth = new Node("G"); Node seventh = new Node("H"); Node eghit = new Node("I"); Node nineth = new Node("G"); //以下是建立二叉樹之間的關係 root.left=first; root.right=second; first.left=third; second.left=foth; second.right=fifth; third.right=seventh; third.left=nineth; foth.right=eghit; // Node root.left.left = new Node("D"); Recursive(root); } //以下是二叉樹遞迴遍曆的主題代碼演算法函數 public static void Recursive(Node node){ if(node.value==""){ System.out.println("這是一顆空樹!"); //測試根節點是否為空白,並且為程式的出口 }else{ System.out.print(node.value); } if(node.left!=null){ Recursive(node.left); //遞迴左子樹的節點 } if(node.right!=null){ Recursive(node.right); //遞迴右子樹的節點 } } }
列印查來的結果為:
run:
ABDGHCEIF成功構建 (總時間: 0 秒)
二叉樹非遞迴遍曆,不用棧使O(1)之java:
1 package rest; 2 3 //構造節點,產生一顆樹 4 class Nod 5 { 6 Nod(String Letter){ //建構函式 7 value=Letter; 8 } 9 public Nod per; //為了實現不用棧,使O(1),記錄他的父節點10 public Nod left; //左節點11 public Nod right; //右節點12 public String value; 13 public int flag=0; //訪問標誌位14 }15 public class Cycles 16 {17 public static void main(String[] args) 18 {19 //以下是構建中的二叉樹,從根節點起一層一層的構建20 Nod root = new Nod("A");21 Nod first = new Nod("B");22 Nod second = new Nod("C");23 Nod third = new Nod("D");24 Nod foth = new Nod("E");25 Nod fifth = new Nod("F"); 26 Nod sixth = new Nod("G");27 Nod seventh = new Nod("H");28 Nod eghit = new Nod("I");29 Nod set =new Nod("sdfsa");30 //以下是建立二叉樹之間的關係 31 root.left=first;32 root.right=second;33 first.per = root;34 first.left=third;35 36 37 second.per=root;38 second.left=foth;39 second.right=fifth;40 41 third.per=first;42 third.right=seventh;43 third.left=sixth;44 45 foth.per=second;46 foth.right=eghit;47 fifth.per=second;48 49 sixth.per=third;50 seventh.per=third;51 eghit.per=foth;52 53 if(root==null){54 System.out.println("這是一顆空樹"); 55 }56 57 Nod index=root;58 while(index!=null){59 if(index.flag==0){60 System.out.print(index.value);61 62 index.flag=1;63 }64 if(index.left!=null&&index.left.flag==0){65 index=index.left; 66 }else{67 if(index.right!=null&&index.right.flag==0){68 index=index.right;69 }else{70 index = index.per; //回溯自己的父節點71 } 72 73 }74 }75 76 77 78 }79 }
run:
ABDGHCEIF成功構建 (總時間: 0 秒)
總結:我在調試這個的時候出現的幾點問題:
我在回溯父節點的那段代碼時,一開始嘗試的是通過回溯父節點,然後再指向自己的子節點,判斷是否為空白,來測試代碼是否運行到該行下,但是卻行不通.
代碼如下:
if(index.right==null){
System.out.print("代碼可運行至此");
}else{
System.out.print("代碼無法判斷右節點");
}
但是結果卻是,什麼都沒有顯示,尼瑪真的什麼都沒有顯示。。。。我就無語了,好在不影響代碼實現。
2.但是我在測試System.out.print(index.right.value);居然可以!居然可以!這一點還不太明白。
二叉樹非遞迴遍曆,使用棧之java:
既然要用到棧,那就要說明一下棧是什嗎???棧無非就是先進後出的資料結構,我們可以引進import java.util.Stack;但是也可以自己寫。
棧主要的操作有
1.public Stack() 建立一個空堆棧類
2.public boolean empty() 帶布爾傳回值的函數,測試堆棧是否為空白;
3.public pop() 彈出堆棧頂部的對象,並作為此函數的值返回該對象,輸出 ,出棧操作
4.public push() 壓棧操作
5.public peek() 查看堆棧頂部的對象,但不從堆棧中移除它。 起標記作用
6.public boolean full() 滿棧
1 package rest; 2 3 /** 4 * 5 * @author 曹想- 6 */ 7 class Stack 8 { 9 private Nod2 StackArr[] ;10 private int top;11 public Stack(){12 this.top=-1; //之所以是以-1開始是因為數組是以0為開始13 this.StackArr = new Nod2[50]; //限定長度為5014 }15 public void push(Nod2 index){16 StackArr[++top]=index;17 }18 public Nod2 pop(){19 return StackArr[top--]; //出棧操作20 }21 public boolean isempty(){ //判斷是否為空白22 return this.top==-1;23 }24 25 }26 27 class Nod228 {29 Nod2(String Letter){ //建構函式30 value=Letter;31 }32 public Nod2 left; //左節點33 public Nod2 right; //右節點34 public String value; 35 }36 37 public class Test2{38 public static void main(String arg[]){39 //以下是構建中的二叉樹,從根節點起一層一層的構建40 Nod2 root = new Nod2("A");41 Nod2 first = new Nod2("B");42 Nod2 second = new Nod2("C");43 Nod2 third = new Nod2("D");44 Nod2 foth = new Nod2("E");45 Nod2 fifth = new Nod2("F"); 46 Nod2 sixth = new Nod2("G");47 Nod2 seventh = new Nod2("H");48 Nod2 eghit = new Nod2("I");49 Nod2 set =new Nod2("sdfsa");50 //以下是建立二叉樹之間的關係 51 root.left=first;52 root.right=second;53 54 first.left=third;55 56 57 second.left=foth;58 second.right=fifth;59 60 third.right=seventh;61 third.left=sixth;62 63 64 foth.right=eghit;65 66 67 68 //以下是利用棧的實現 69 Stack st = new Stack();70 if(root==null){71 System.out.println("這是一顆空樹");72 }73 74 Nod2 index = root;75 while (index != null || !st.isempty()) { //如果index為空白說明節點遍曆完了,棧為空白說明已經完成遍曆76 while (index != null) { //先遍曆左子樹,並列印節點,將節入棧 77 System.out.print(index.value); 78 st.push(index); 79 index = index.left; 80 } 81 if (!st.isempty()) { //將節點出棧,遍曆右節點82 index = st.pop(); 83 index = index.right; 84 } 85 } 86 }87 }
非遞迴棧的另一種演算法:
Stack st = new Stack();
if(root==null){
System.out.println("這是一顆空樹");
}
Nod2 index = root;
int n=9; //這裡的n是節點的個數,由一開始輸入節點的個數決定
while(n--!=0){
System.out.println(index.value); //輸出遍曆節點值
st.push(index); //將節點值入棧
if(index.left!=null){
index = index.left; //遍曆左節點
}else{
while(!st.isempty()){ //棧不為空白,則迴圈
Nod2 Tem = st.pop().right; //右節點不為空白則設定右節點為index遍曆
if(Tem!=null){
index =Tem;
break;
}
}
}
}
QQ:1689986723
歡迎批評指正!
資料結構二叉樹的遞迴與非遞迴遍曆之 實現可編譯(1)java