本文學習上文提到的二叉樹實現的第二個方法:建立二叉樹類。
首先補一個知識點:前面我們用遞歸實現了遍歷,那麼我們是否能用非遞歸結構實現遍歷呢?答案是:可以的。在遞歸學習中我們知道轉換的方法通常有兩種,都要用到堆棧,因此,即便是不分析遍歷特點我們也知道是堆棧。
分析:前序遍歷中,在所有未被訪問的結點中,已訪問的結點中最後訪問(輸出)結點的左子樹的根結點將最先被訪問,因此堆棧設計如下:
(1)初始化堆棧;
(2)根結點入棧;
(3)堆棧非空時:a、出棧取棧頂結點,訪問(輸出)該結點;b、若右孩子非空,入棧;c、若左孩子非空,入棧;
(4)結束;
該算法和層序遍歷算法結構非常類似,可以一起記憶學習,其算法代碼如下(使用時要加入Traverse類中):
public static void preOrderNoRecur(BiTreeNode root)throws Exception{
LinStack s = new LinStack();//創建鏈式堆棧
if(root==null) return;
BiTreeNode curr;
s.push(root);//根結點入棧
while(!s.isEmpty()){
curr = (BiTreeNode)s.pop();
System.out.print(" "+curr.data);
if(curr.getRight()!=null)
s.push(curr.getRight());
if(curr.getLeft()!=null)
s.push(curr.getLeft());
}
}
接着說建立二叉樹類來實現二叉樹設計,代碼如下:
package Tree;
/**
* @author sun
* 創建時間:2017年4月24日上午9:13:29
*/
//在二叉樹結點類的基礎上設計二叉樹類
public class BiTree {
private BiTreeNode root;//根“指針”
private void preOrder(BiTreeNode t,Visit vs){
//前序遍歷二叉樹t,訪問結點操作爲vs.print(t.data)
if(t!=null){
vs.print(t.data);
preOrder(t.getLeft(),vs);
preOrder(t.getRight(),vs);
}
}
private void inOrder(BiTreeNode t,Visit vs){
//中序遍歷二叉樹t
if(t!=null){
inOrder(t.getLeft(),vs);
vs.print(t.data);
inOrder(t.getRight(),vs);
}
}
private void postOrder(BiTreeNode t,Visit vs){
//後序遍歷二叉樹t
if(t!=null){
postOrder(t.getLeft(),vs);
postOrder(t.getRight(),vs);
vs.print(t.data);
}
}
BiTree(){
root = null;
}
BiTree(Object item,BiTree left,BiTree right){
BiTreeNode l,r;
if(left==null) l = null;
else l = left.root;
if(right==null) r = null;
else r = right.root;
root = new BiTreeNode(item,l,r);
}
public void preOrder(Visit vs){
preOrder(root,vs);
}
public void inOrder(Visit vs){
inOrder(root,vs);
}
public void postOrder(Visit vs){
postOrder(root,vs);
}
}
主函數測試:package Tree;
/**
* @author sun
* 創建時間:2017年4月24日上午9:26:17
*/
public class TestBiTree {
public static void main(String[] args) {
BiTree g = new BiTree(new Character('G'),null,null);
BiTree d = new BiTree(new Character('D'),null,g);
BiTree b = new BiTree(new Character('B'),d,null);
BiTree e = new BiTree(new Character('E'),null,null);
BiTree f = new BiTree(new Character('F'),null,null);
BiTree c = new BiTree(new Character('C'),e,f);
BiTree a = new BiTree(new Character('A'),b,c);
Visit vs = new Visit();
System.out.print("前序遍歷結點序列爲:");
a.preOrder(vs);
System.out.println();
System.out.print("中序遍歷結點序列爲:");
a.inOrder(vs);
System.out.println();
System.out.print("後序遍歷結點序列爲:");
a.postOrder(vs);
System.out.println();
}
}
/*
前序遍歷結點序列爲:A B D G C E F
中序遍歷結點序列爲:D G B A E C F
後序遍歷結點序列爲:G D B E F C A
*/