關于二叉樹的基本概念前面已經有所涉及,這里不在贅述:
一些基本概念可以參考這里:
http://blog.csdn.net/yalishadaa/article/details/54851324
下面直接使用代碼實現:
package bbb;public class TreeNode { PRivate TreeNode left; private TreeNode right; private char data; public TreeNode(char data,TreeNode left, TreeNode right) { super(); this.left = left; this.right = right; this.data = data; } public TreeNode(char data) { super(); this.data = data; } public TreeNode getLeft() { return left; } public void setLeft(TreeNode left) { this.left = left; } public TreeNode getRight() { return right; } public void setRight(TreeNode right) { this.right = right; } public char getData() { return data; } public void setData(char data) { this.data = data; } }package bbb;public class Bintree { public TreeNode initTree(){ TreeNode A=new TreeNode('A'); TreeNode B=new TreeNode('B',A,null); TreeNode C=new TreeNode('C'); TreeNode D=new TreeNode('D',B,C); TreeNode E=new TreeNode('E'); TreeNode F=new TreeNode('F',E,null); TreeNode G=new TreeNode('G',null,F); TreeNode H=new TreeNode('H',D,G); return H; } public void visitNode(TreeNode node){ System.out.print(node.getData()+" "); } //先序遍歷 public void preOrder(TreeNode t){ if(t!=null){ visitNode(t); preOrder(t.getLeft()); preOrder(t.getRight()); } } //中序遍歷 public void midOrder(TreeNode t){ if(t!=null){ midOrder(t.getLeft()); visitNode(t); midOrder(t.getRight()); } } //后續遍歷 public void tailOrder(TreeNode t){ if(t!=null){ tailOrder(t.getLeft()); tailOrder(t.getRight()); visitNode(t); } } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Bintree myTree=new Bintree(); TreeNode t=myTree.initTree(); myTree.preOrder(t); System.out.println(); myTree.midOrder(t); System.out.println(); myTree.tailOrder(t); }}最后是輸出的結果:
前面遍歷二叉樹是使用遞歸方式實現的,效率比較低下,下面使用非遞歸方式遍歷二叉樹,使用一個堆棧來存放節點,
具體的規則如下:
1.前序遍歷
對于任一節點P,
1)輸出節點P,然后將其入棧,再看P的左孩子是否為空;
2)若P的左孩子不為空,則置P的左孩子為當前節點,重復1)的操作;
3)若P的左孩子為空,則將棧頂節點出棧,但不輸出,并將出棧節點的右孩子置為當前節點,看其是否為空;
4)若不為空,則循環至1)操作;
5)如果為空,則繼續出棧,但不輸出,同時將出棧節點的右孩子置為當前節點,看其是否為空,重復4)和5)操作;
6)直到當前節點P為NULL并且棧空,遍歷結束。2.中序遍歷
對于任一節點P,
1)若P的左孩子不為空,則將P入棧并將P的左孩子置為當前節點,然后再對當前節點進行相同的處理;
2)若P的左孩子為空,則輸出P節點,而后將P的右孩子置為當前節點,看其是否為空;
3)若不為空,則重復1)和2)的操作;
4)若為空,則執行出棧操作,輸出棧頂節點,并將出棧的節點的右孩子置為當前節點,看起是否為空,重復3)和4)的操作;
5)直到當前節點P為NULL并且棧為空,則遍歷結束。
3.后序遍歷對于任一節點P,
1)先將節點P入棧;
2)若P不存在左孩子和右孩子,或者P存在左孩子或右孩子,但左右孩子已經被輸出,則可以直接輸出節點P,并將其出棧,將出棧節點P標記為上一個輸出的節點,再將此時的棧頂結點設為當前節點;
3)若不滿足2)中的條件,則將P的右孩子和左孩子依次入棧,當前節點重新置為棧頂結點,之后重復操作2);
4)直到棧空,遍歷結束。
具體的實現代碼如下:
//非遞歸方式實現 public void unPreOrder(TreeNode t){ Stack< TreeNode> s=new Stack<TreeNode>(); while (t != null || !s.empty()) { while (t != null) { visitNode(t) ; s.push(t); t = t.getLeft(); } if (!s.empty()) { t = s.pop(); t = t.getRight(); } } } public void unmidOrder(TreeNode t){ Stack< TreeNode> s=new Stack<TreeNode>(); while (t != null || !s.empty()) { while (t != null) { s.push(t); t = t.getLeft(); } if (!s.empty()) { t = s.pop(); visitNode(t) ; t = t.getRight(); } } } public void untailOrder(TreeNode t){ Stack<TreeNode> s = new Stack<TreeNode>(); Stack<Integer> s2 = new Stack<Integer>(); Integer i = new Integer(1); while (t != null || !s.empty()) { while (t != null) { s.push(t); s2.push(new Integer(0)); t = t.getLeft(); } while (!s.empty() && s2.peek().equals(i)) { s2.pop(); visitNode(s.pop()); } if (!s.empty()) { s2.pop(); s2.push(new Integer(1)); t = s.peek(); t = t.getRight(); } } }最后是輸出的結果:
新聞熱點
疑難解答