二叉树的前序、中序、后序遍历

来源:互联网 发布:微信淘宝客封号 编辑:程序博客网 时间:2024/05/20 08:26

递归方式:

  1. /** 
  2.  * 实现二叉树的创建、前序遍历、中序遍历和后序遍历 
  3.  **/  
  4. package DataStructure;  
  5.   
  6. /** 
  7.  * Copyright 2014 by Ruiqin Sun 
  8.  * All right reserved 
  9.  * created  on 2014-9-9 下午2:34:15 
  10.  **/  
  11. public class BinTreeInt {  
  12.     private Node root;  
  13.       
  14.     /** 
  15.      * 创建内部节点类 
  16.      **/  
  17.     private class Node{  
  18. //      左节点  
  19.         private Node leftChild;  
  20. //      右节点  
  21.         private Node rightChild;  
  22. //      节点对应的值  
  23.         private int data;  
  24.           
  25.         public Node(int data){  
  26.             this.leftChild = null;  
  27.             this.rightChild = null;  
  28.             this.data = data;  
  29.         }  
  30.     }// class Node  
  31.       
  32.     public BinTreeInt(){  
  33.         root = null;  
  34.     }  
  35.       
  36.     /* 
  37.      *递归的创建二叉树 
  38.      * */  
  39.     public void buildTree(Node node ,int data){  
  40.         if (root == null){// 如果根节点为空,创建根节点  
  41.             root = new Node(data);  
  42.         }else{  
  43.             if(data <node.data){//插入到左子树  
  44.                 if(node.leftChild == null){//左节点为空,直接创建值为data的左节点  
  45.                     node.leftChild = new Node(data);  
  46.                 }else{//左节点不为空,调用buildTree函数插到左子树中  
  47.                     buildTree(node.leftChild,data);  
  48.                 }  
  49.             }else{  
  50.                 if(node.rightChild == null){  
  51.                     node.rightChild = new Node(data);  
  52.                 }else{  
  53.                     buildTree(node.rightChild,data);  
  54.                 }  
  55.             }         
  56.         }  
  57.     }//end buildTree  
  58.     /* 
  59.      *前序遍历二叉树 
  60.      * */  
  61.     public void preOrder(Node node){  
  62.         if(node != null){  
  63.             System.out.print(node.data);  
  64.             preOrder(node.leftChild);  
  65.             preOrder(node.rightChild);  
  66.         }  
  67.     }  
  68.     /* 
  69.      *中序遍历二叉树 
  70.      * */  
  71.     public void inOrder(Node node){  
  72.         if(node != null){  
  73.             inOrder(node.leftChild);  
  74.             System.out.print(node.data);  
  75.             inOrder(node.rightChild);  
  76.         }  
  77.     }  
  78.     /* 
  79.      *后序遍历二叉树 
  80.      * */  
  81.     public void postOrder(Node node){  
  82.         if(node != null){  
  83.             postOrder(node.leftChild);  
  84.             postOrder(node.rightChild);  
  85.             System.out.print(node.data);              
  86.         }  
  87.     }  
  88.       
  89.     public static void main(String ars[]){  
  90.         int[] a={2,4,12,45,21,6,111};  
  91.         BinTreeInt binTree = new BinTreeInt();  
  92.         for(int i = 0; i<a.length; i++){  
  93.             binTree.buildTree(binTree.root, a[i]);  
  94.         }  
  95.         System.out.print("前序遍历");  
  96.         binTree.preOrder(binTree.root);  
  97.         System.out.println("");  
  98.         System.out.print("中序遍历");  
  99.         binTree.inOrder(binTree.root);  
  100.         System.out.println("");  
  101.         System.out.print("后序遍历");  
  102.         binTree.postOrder(binTree.root);  
  103.     }  
  104. }  


栈的实现:

  1. /** 
  2.  *  
  3.  * @author kerryfish 
  4.  * JAVA实现二叉树的先序、中序、后序、层序遍历 
  5.  * 递归和非递归版本 
  6.  * 
  7.  */  
  8.   
  9. class Node{  
  10.     public int value;  
  11.     public Node left;  
  12.     public Node right;  
  13.     public Node(int v){  
  14.         this.value=v;  
  15.         this.left=null;  
  16.         this.right=null;  
  17.     }  
  18.       
  19. }  
  20. class BinaryTreeTraversal { 
  21.     /** 
  22.      *  
  23.      * @param root 树根节点 
  24.      * 利用栈实现循环先序遍历二叉树 
  25.      * 这种实现类似于图的深度优先遍历(DFS) 
  26.      * 维护一个栈,将根节点入栈,然后只要栈不为空,出栈并访问,接着依次将访问节点的右节点、左节点入栈。 
  27.      * 这种方式应该是对先序遍历的一种特殊实现(看上去简单明了),但是不具备很好的扩展性,在中序和后序方式中不适用 
  28.      */  
  29.     public static void preOrderStack_1(Node root){  
  30.         if(root==null)return;  
  31.         Stack<Node> s=new Stack<Node>();  
  32.         s.push(root);  
  33.         while(!s.isEmpty()){  
  34.             Node temp=s.pop();  
  35.             System.out.println(temp.value);  
  36.             if(temp.right!=null) s.push(temp.right);  
  37.             if(temp.left!=null) s.push(temp.left);  
  38.         }  
  39.     }  
  40.     /** 
  41.      *  
  42.      * @param root 树的根节点 
  43.      * 利用栈模拟递归过程实现循环先序遍历二叉树 
  44.      * 这种方式具备扩展性,它模拟递归的过程,将左子树点不断的压入栈,直到null,然后处理栈顶节点的右子树 
  45.      */  
  46.     public static void preOrderStack_2(Node root){  
  47.         if(root==null)return;  
  48.         Stack<Node> s=new Stack<Node>();  
  49.         while(root!=null||!s.isEmpty()){  
  50.             while(root!=null){  
  51.                 System.out.println(root.value);  
  52.                 s.push(root);//先访问再入栈  
  53.                 root=root.left;  
  54.             }  
  55.             root=s.pop();  
  56.             root=root.right;//如果是null,出栈并处理右子树  
  57.         }  
  58.     }  
  59.     /** 
  60.      *  
  61.      * @param root 树根节点 
  62.      * 利用栈模拟递归过程实现循环中序遍历二叉树 
  63.      * 思想和上面的preOrderStack_2相同,只是访问的时间是在左子树都处理完直到null的时候出栈并访问。 
  64.      */  
  65.     public static void inOrderStack(Node root){  
  66.         if(root==null)return;  
  67.         Stack<Node> s=new Stack<Node>();  
  68.         while(root!=null||!s.isEmpty()){  
  69.             while(root!=null){  
  70.                 s.push(root);//先访问再入栈  
  71.                 root=root.left;  
  72.             }  
  73.             root=s.pop();  
  74.             System.out.println(root.value);  
  75.             root=root.right;//如果是null,出栈并处理右子树  
  76.         }  
  77.     }  
  78.     /** 
  79.      *  
  80.      * @param root 树根节点 
  81.      * 后序遍历不同于先序和中序,它是要先处理完左右子树,然后再处理根(回溯),所以需要一个记录哪些节点已经被访问的结构(可以在树结构里面加一个标记),这里可以用map实现 
  82.      */  
  83.     public static void postOrderStack(Node root){  
  84.         if(root==null)return;  
  85.         Stack<Node> s=new Stack<Node>();  
  86.         Map<Node,Boolean> map=new HashMap<Node,Boolean>();   
  87.         s.push(root);  
  88.         while(!s.isEmpty()){  
  89.             Node temp=s.peek();  
  90.             if(temp.left!=null&&!map.containsKey(temp.left)){  
  91.                 temp=temp.left;  
  92.                 while(temp!=null){  
  93.                     if(map.containsKey(temp))break;  
  94.                     else s.push(temp);  
  95.                     temp=temp.left;  
  96.                 }  
  97.                 continue;  
  98.             }  
  99.             if(temp.right!=null&&!map.containsKey(temp.right)){  
  100.                 s.push(temp.right);  
  101.                 continue;  
  102.             }  
  103.             Node t=s.pop();  
  104.             map.put(t,true);  
  105.             System.out.println(t.value);  
  106.         }  
  107.     }  
  108.     /** 
  109.      *  
  110.      * @param root 树根节点 
  111.      * 层序遍历二叉树,用队列实现,先将根节点入队列,只要队列不为空,然后出队列,并访问,接着讲访问节点的左右子树依次入队列 
  112.      */  
  113.     public static void levelTravel(Node root){  
  114.         if(root==null)return;  
  115.         Queue<Node> q=new LinkedList<Node>();  
  116.         q.add(root);  
  117.         while(!q.isEmpty()){  
  118.             Node temp =  q.poll();  
  119.             System.out.println(temp.value);  
  120.             if(temp.left!=null)q.add(temp.left);  
  121.             if(temp.right!=null)q.add(temp.right);  
  122.         }  
  123.     }  
  124. }  






0 0