遞歸方式:
- /**
- * 實現二叉樹的創建、前序遍歷、中序遍歷和後序遍歷
- **/
- package DataStructure;
- /**
- * Copyright 2014 by Ruiqin Sun
- * All right reserved
- * created on 2014-9-9 下午2:34:15
- **/
- public class BinTreeInt {
- private Node root;
- /**
- * 創建內部節點類
- **/
- private class Node{
- // 左節點
- private Node leftChild;
- // 右節點
- private Node rightChild;
- // 節點對應的值
- private int data;
- public Node(int data){
- this.leftChild = null;
- this.rightChild = null;
- this.data = data;
- }
- }// class Node
- public BinTreeInt(){
- root = null;
- }
- /*
- *遞歸的創建二叉樹
- * */
- public void buildTree(Node node ,int data){
- if (root == null){// 如果根節點爲空,創建根節點
- root = new Node(data);
- }else{
- if(data <node.data){//插入到左子樹
- if(node.leftChild == null){//左節點爲空,直接創建值爲data的左節點
- node.leftChild = new Node(data);
- }else{//左節點不爲空,調用buildTree函數插到左子樹中
- buildTree(node.leftChild,data);
- }
- }else{
- if(node.rightChild == null){
- node.rightChild = new Node(data);
- }else{
- buildTree(node.rightChild,data);
- }
- }
- }
- }//end buildTree
- /*
- *前序遍歷二叉樹
- * */
- public void preOrder(Node node){
- if(node != null){
- System.out.print(node.data);
- preOrder(node.leftChild);
- preOrder(node.rightChild);
- }
- }
- /*
- *中序遍歷二叉樹
- * */
- public void inOrder(Node node){
- if(node != null){
- inOrder(node.leftChild);
- System.out.print(node.data);
- inOrder(node.rightChild);
- }
- }
- /*
- *後序遍歷二叉樹
- * */
- public void postOrder(Node node){
- if(node != null){
- postOrder(node.leftChild);
- postOrder(node.rightChild);
- System.out.print(node.data);
- }
- }
- public static void main(String ars[]){
- int[] a={2,4,12,45,21,6,111};
- BinTreeInt binTree = new BinTreeInt();
- for(int i = 0; i<a.length; i++){
- binTree.buildTree(binTree.root, a[i]);
- }
- System.out.print("前序遍歷");
- binTree.preOrder(binTree.root);
- System.out.println("");
- System.out.print("中序遍歷");
- binTree.inOrder(binTree.root);
- System.out.println("");
- System.out.print("後序遍歷");
- binTree.postOrder(binTree.root);
- }
- }
棧的實現:
- /**
- *
- * @author kerryfish
- * JAVA實現二叉樹的先序、中序、後序、層序遍歷
- * 遞歸和非遞歸版本
- *
- */
- class Node{
- public int value;
- public Node left;
- public Node right;
- public Node(int v){
- this.value=v;
- this.left=null;
- this.right=null;
- }
- }
- class BinaryTreeTraversal {
- /**
- *
- * @param root 樹根節點
- * 利用棧實現循環先序遍歷二叉樹
- * 這種實現類似於圖的深度優先遍歷(DFS)
- * 維護一個棧,將根節點入棧,然後只要棧不爲空,出棧並訪問,接着依次將訪問節點的右節點、左節點入棧。
- * 這種方式應該是對先序遍歷的一種特殊實現(看上去簡單明瞭),但是不具備很好的擴展性,在中序和後序方式中不適用
- */
- public static void preOrderStack_1(Node root){
- if(root==null)return;
- Stack<Node> s=new Stack<Node>();
- s.push(root);
- while(!s.isEmpty()){
- Node temp=s.pop();
- System.out.println(temp.value);
- if(temp.right!=null) s.push(temp.right);
- if(temp.left!=null) s.push(temp.left);
- }
- }
- /**
- *
- * @param root 樹的根節點
- * 利用棧模擬遞歸過程實現循環先序遍歷二叉樹
- * 這種方式具備擴展性,它模擬遞歸的過程,將左子樹點不斷的壓入棧,直到null,然後處理棧頂節點的右子樹
- */
- public static void preOrderStack_2(Node root){
- if(root==null)return;
- Stack<Node> s=new Stack<Node>();
- while(root!=null||!s.isEmpty()){
- while(root!=null){
- System.out.println(root.value);
- s.push(root);//先訪問再入棧
- root=root.left;
- }
- root=s.pop();
- root=root.right;//如果是null,出棧並處理右子樹
- }
- }
- /**
- *
- * @param root 樹根節點
- * 利用棧模擬遞歸過程實現循環中序遍歷二叉樹
- * 思想和上面的preOrderStack_2相同,只是訪問的時間是在左子樹都處理完直到null的時候出棧並訪問。
- */
- public static void inOrderStack(Node root){
- if(root==null)return;
- Stack<Node> s=new Stack<Node>();
- while(root!=null||!s.isEmpty()){
- while(root!=null){
- s.push(root);//先訪問再入棧
- root=root.left;
- }
- root=s.pop();
- System.out.println(root.value);
- root=root.right;//如果是null,出棧並處理右子樹
- }
- }
- /**
- *
- * @param root 樹根節點
- * 後序遍歷不同於先序和中序,它是要先處理完左右子樹,然後再處理根(回溯),所以需要一個記錄哪些節點已經被訪問的結構(可以在樹結構裏面加一個標記),這裏可以用map實現
- */
- public static void postOrderStack(Node root){
- if(root==null)return;
- Stack<Node> s=new Stack<Node>();
- Map<Node,Boolean> map=new HashMap<Node,Boolean>();
- s.push(root);
- while(!s.isEmpty()){
- Node temp=s.peek();
- if(temp.left!=null&&!map.containsKey(temp.left)){
- temp=temp.left;
- while(temp!=null){
- if(map.containsKey(temp))break;
- else s.push(temp);
- temp=temp.left;
- }
- continue;
- }
- if(temp.right!=null&&!map.containsKey(temp.right)){
- s.push(temp.right);
- continue;
- }
- Node t=s.pop();
- map.put(t,true);
- System.out.println(t.value);
- }
- }
- /**
- *
- * @param root 樹根節點
- * 層序遍歷二叉樹,用隊列實現,先將根節點入隊列,只要隊列不爲空,然後出隊列,並訪問,接着講訪問節點的左右子樹依次入隊列
- */
- public static void levelTravel(Node root){
- if(root==null)return;
- Queue<Node> q=new LinkedList<Node>();
- q.add(root);
- while(!q.isEmpty()){
- Node temp = q.poll();
- System.out.println(temp.value);
- if(temp.left!=null)q.add(temp.left);
- if(temp.right!=null)q.add(temp.right);
- }
- }
- }