JAVA下实现二叉树的先序、中序、后序、层序遍历(递归和循环) JAVA下实现二叉树的先序、中序、后序、层序遍历(递归和循环)

原文:https://blog.csdn.net/kerryfish/article/details/24309617

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

猜你喜欢

转载自blog.csdn.net/notonlyrush/article/details/80207508