方法一,思想是從根節點一直向左邊走,邊走邊列印,左邊走不通了,出棧向右邊走,邊界條件是current!=null或者棧非空
public void preorder1()
//中間節點不可以再次向左邊走
current=s.pop().rightchild;
}system.out.println();
}
方法二,使用棧先進後出的特性,簡潔,我喜歡。先將中間節點出棧列印,然後依次將右孩子、左孩子入棧,迴圈該步驟。
public void preorder2()
system.out.println();
}
方法一,類似於先序遍歷的方法一,在列印順序上略有不同
public void inorder1()
node n=s.pop();
system.out.print(n.data+" ");
current=n.rightchild;
}system.out.println();
}
方法二,有時候我們不想使用current!=null||!s.isempty()這個邊界條件,想用簡單一點迴圈終止條件!s.isempty()。
兩種方法,一種是在向左搜尋和向右搜尋時,遇到null也入棧,可以保證即使右孩子為null,棧也非空;另一種是向右搜尋時做判斷,右孩子為空時向上回溯,非空時將右孩子入棧,這就是下面的這種處理方式:
//ps:如果把null也放入棧中,會使**簡潔一點
public void inorder2()
//棧非空 且都無右節點 往上回溯
while(!s.isempty()&&((node) s.peek()).rightchild==null)
if(!s.isempty())
}system.out.println();
}
後序遍歷較前兩種複雜一點,主要是由於後序遍歷時,要經過中間節點兩次,每次經過的我們就要想 是出棧列印呢還是向右搜尋呢,如果右孩子為空,當然直接出棧列印,如果右孩子不為空呢,那麼我們要進行乙個判斷,
方法一:可以使用flag標記,第一次由中間節點到達右孩子時,flag=1,第二次由右孩子返回中間節點時,判斷flag==1即可知右子樹已經遍歷完了,將中間節點出棧列印
方法二:記錄下前乙個節點pre,經過中間節點時判斷,當右孩子為空或者cur.rightchild==pre即pre等於右孩子,則將中間節點出棧列印,否則向右搜尋右子樹
方法三:使用棧先進後出的特性,中間節點peek後先右孩子入棧再左孩子入棧。這裡要做處理,記錄下前乙個節點,當current.leftchild==pre||current.rightchild==pre時,表示中間節點的左右子樹已經遍歷過了,將中間節點列印出棧,否則就要考慮將右左孩子入棧。注意:該方法開始時並沒有一下子向左遍歷到左下節點。
下面是上面三種方法的**:
public void postorder1()
cur=s.peek();
if(cur.rightchild==null||cur.flag==1)else
} system.out.println();
}
public void postorder2()
cur=s.peek();
if(cur.rightchild==null||cur.rightchild==pre)else
} system.out.println();
}
//和方法二類似,但是用到了棧的特性,故不用先一直搜尋到左下節點
public void postorder3()
if(current.leftchild!=null&¤t.leftchild!=pre&¤t.rightchild!=pre)
if(current.leftchild==null&¤t.rightchild==null)
if(current.leftchild==pre||current.rightchild==pre)
} system.out.println();
}
方法四:
下面還有一種方法,使用雙棧法,相當巧妙,我很喜歡,注意這一次棧s1是先將左孩子入棧,再將右孩子入棧的。public void postorder4()
while(!s2.isempty())
system.out.println();
}
二叉樹遍歷(遞迴 非遞迴)
二叉樹以及對二叉樹的三種遍歷 先根,中根,後根 的遞迴遍歷演算法實現,以及先根遍歷的非遞迴實現。node public class node public node left public node right public object value 遍歷訪問操作介面 public inte ce ...
二叉樹非遞迴遍歷
二叉樹非遞迴遍歷的幾個要點 1 不管前序 中序還是後序,它們的遍歷路線 或者說是回溯路線,先沿左邊一直走到盡頭,然後回溯到某節點,並跳轉到該節點的右孩子 如果有的話 然後又沿著這個有孩子的左邊一直走到盡頭 都是一樣的。2 明確每次回溯的目的。比如,前序回溯的目的是為了訪問右子樹 中序回溯的目的是為了...
非遞迴遍歷二叉樹
中序遞迴遍歷 void inordertrvdigui node pnode 然而,當樹的深度很大 比如16 時 假設為滿二叉樹 樹的節點數為 2 0 2 1 2 2 2 15 2 16 65536,遍歷整個二叉樹意味著有65536次函式呼叫,這將極大地增加程式執行時間。這時,應該採取非遞迴便利二叉...