递归和非递归实现 先序、中序、后序遍历二叉树


递归和非递归实现 先序、中序、后序遍历二叉树

先序、中序、后序遍历二叉树是一个基础又非常重要的知识点,频繁出现在《剑指offer》面试题中,很多题目都是二叉树遍历的变形。

所以在本文章中,我总结了用递归和非递归的方法分别实现对二叉树的先序、中序和后序遍历。

  • 递归实现三种遍历

    • 先序遍历

      package algorithm.tree;
      
      /**
       * 
       * @author FHY
       * 递归实现
       * 按照先序遍历树的顺序打印树结点
       */
      
      /*
       * 树节点定义
       */
      class TreeNode{
      	int val = 0;
      	TreeNode left;
      	TreeNode right;
      	public TreeNode(int val){
      		this.val = val;
      	}
      }
      
      /* 二叉树结构如下:
      * 
      *        0
      *      /   \
      *     1     2
      *    / \   / \
      *   3   4 5   6
      *  
      * 先序遍历结果:0 1 3 4 2 5 6
      */
      
      public class PreOrderTraversal {
          public static void main(String[] args) {			
      		TreeNode root = new TreeNode(0);
      		TreeNode node1 = new TreeNode(1);
      		TreeNode node2 = new TreeNode(2);
      		TreeNode node3 = new TreeNode(3);
      		TreeNode node4 = new TreeNode(4);
      		TreeNode node5 = new TreeNode(5);
      		TreeNode node6 = new TreeNode(6);
      		
      		root.left = node1;
      		root.right = node2;
      		node1.left = node3;
      		node1.right = node4;
      		node2.left = node5;
      		node2.right = node6;
      		printPreOrderTreeNode(root);
      	}
      	
          private static void printPreOrderTreeNode(TreeNode root) {
      		if(root == null)
      			return;
      		System.out.println(root.val);
      		printPreOrderTreeNode(root.left);
      		printPreOrderTreeNode(root.right);
      	}	
      }
      
    • 中序遍历

      package algorithm.tree;
      
      /**
       * 
       * @author FHY
       * 递归实现
       * 按照中序遍历树节点的顺序打印树节点
       */
      
      /* 新建二叉树如下:
      * 
      *        0
      *      /   \
      *     1     2
      *    / \   / \
      *   3   4 5   6
      *   
      * 中序遍历结果:3 1 4 0 5 2 6
      */	
      public class InOrderTraversal_1 {       
      	public static void main(String[] args) {
      		TreeNode root = new TreeNode(0);
      		TreeNode node1 = new TreeNode(1);
      		TreeNode node2 = new TreeNode(2);
      		TreeNode node3 = new TreeNode(3);
      		TreeNode node4 = new TreeNode(4);
      		TreeNode node5 = new TreeNode(5);
      		TreeNode node6 = new TreeNode(6);
      		
      		root.left = node1;
      		root.right = node2;
      		node1.left = node3;
      		node1.right = node4;
      		node2.left = node5;
      		node2.right = node6;
      		printInOrderTreeNode(root);
      	}
      	
          private static void printInOrderTreeNode(TreeNode root) {
      		if(root.left != null)
      			printInOrderTreeNode(root.left);
      		System.out.println(root.val);
      		if(root.right != null)
      			printInOrderTreeNode(root.right);
      	}     
      }
      
      
    • 后序遍历

      package algorithm.tree;
      
      /**
       * 
       * @author FHY
       * 递归实现
       * 按照后序遍历树节点的顺序打印树节点
       */
      
      /* 新建二叉树如下:
       * 
       *        0
       *      /   \
       *     1     2
       *    / \   / \
       *   3   4 5   6
       *   
       * 后序遍历结果:3 4 1 5 6 2 0
       */	
      
      public class PostOrderTraversal {
      	public static void main(String[] args) {		
      		TreeNode root = new TreeNode(0);
      		TreeNode node1 = new TreeNode(1);
      		TreeNode node2 = new TreeNode(2);
      		TreeNode node3 = new TreeNode(3);
      		TreeNode node4 = new TreeNode(4);
      		TreeNode node5 = new TreeNode(5);
      		TreeNode node6 = new TreeNode(6);
      		
      		root.left = node1;
      		root.right = node2;
      		node1.left = node3;
      		node1.right = node4;
      		node2.left = node5;
      		node2.right = node6;
      		postOrderTraversal(root);
      	}	
      	
      	private static void postOrderTraversal(TreeNode root) {
      		if(root == null)
      			return;	
      		if(root.left != null)
      			postOrderTraversal(root.left);
      		if(root.right != null)
      			postOrderTraversal(root.right);
      		
      		System.out.println(root.val);	
      	} 	
      }
      
      
  • 非递归实现三种遍历

    • 先序遍历

      /**
       * Created by FHY on 2019/5/6.
       * 使用非递归方法先序遍历二叉树。
            1
           / \
          2   3
             /
            4
        以上输出为:1->2->3->4
       */
      import java.util.Stack;
      import java.util.ArrayList;
      public class Solution {
          public ArrayList<Integer> preorderTraversal(TreeNode root) {
              ArrayList<Integer> result = new ArrayList<Integer>();
              Stack<TreeNode> stack = new Stack<TreeNode>();           
              if(root == null)
                  return result;  
                            
              stack.push(root);
              TreeNode thisNode = new TreeNode(0);
              
              while(!stack.isEmpty()){
                  thisNode = stack.pop();
                  result.add(thisNode.val);
                  if(thisNode.right != null)
                      stack.push(thisNode.right);
                  if(thisNode.left != null)
                      stack.push(thisNode.left);
              }
              return result;
          }
      }
      
    • 中序遍历

      package offer1;
      import java.util.Stack;
      
      /**
       * Created by FHY on 2019/5/10.
       * 非递归实现树的中序遍历
       *        0
       *      /  \
       *     1    2
       *        /   \
       *       3     4
       * 以上树输出为1,0,3,2,4
       */
      public class InOrderTraverse {
          public static void main(String[] args){
              TreeNode root = new TreeNode(0);
              TreeNode node1 = new TreeNode(1);
              TreeNode node2 = new TreeNode(2);
              TreeNode node3 = new TreeNode(3);
              TreeNode node4 = new TreeNode(4);
              root.left = node1;
              root.right = node2;
              node2.left = node3;
              node2.right = node4;
              getInOrderTraverse(root);
          }
      
          public static void getInOrderTraverse(TreeNode root){
              Stack<TreeNode> stack = new Stack<TreeNode>();
              TreeNode p = root;
              TreeNode thisNode = null;
              while(p != null || !stack.isEmpty()){
                  if(p != null){
                      stack.push(p);
                      p = p.left;
                  }else{
                      thisNode = stack.pop();
                      System.out.println(thisNode.val);
                      p = thisNode.right;
                  }
              }
          }
      }
      
    • 后序遍历

      package offer1;
      
      /**
       * Created by FHY on 2019/5/5.
       * 使用非递归方法后序遍历二叉树。
            1
           / \
          2   3
             /
            4
         以上树输出结果为:2->4->3->1
       * 要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。
       * 如果P不存在左孩子和右孩子,则可以直接访问它;
       * 或者P存在孩子,但是其孩子都已被访问过了,则同样可以直接访问该结点
       * 若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩    子前面被访问,左孩子和右孩子都在根结点前面被访问。
       */
      
      import java.util.Stack;
      import java.util.ArrayList;
      
      //树节点定义
      class TreeNode{
          int val;
          TreeNode left;
          TreeNode right;
          public TreeNode(int val){
              this.val = val;
          }
      }
      
      public class postOrder {
          public static void main(String[] args){
              TreeNode root = new TreeNode(1);
              TreeNode root_left = new TreeNode(2);
              TreeNode root_right = new TreeNode(3);
              root.left = root_left;
              root.right = root_right;
              root_right.left = new TreeNode(4);
              ArrayList result = postorderTraversal(root);
              for(int i = 0; i < result.size(); i++){
                  System.out.println(result.get(i));
              }
          }
          
          public static ArrayList<Integer> postorderTraversal(TreeNode root) {
              ArrayList<Integer> result = new ArrayList<Integer>();
              if(root == null)
                  return result;
              
              Stack<TreeNode> stack = new Stack<TreeNode>();
              stack.push(root);
              TreeNode cur = new TreeNode(0);
              TreeNode pre = null;
              
              while(!stack.isEmpty()){
                  cur = stack.peek();
                  if(cur.left == null && cur.right == null ||
                          (pre != null && (pre == cur.left || pre == cur.right))){
                      result.add(cur.val);
                      pre = cur;
                      stack.pop();
                  }else
                  {
                      if(cur.right != null){
                          stack.push(cur.right);
                      }
                      if(cur.left != null){
                          stack.push(cur.left);
                      }
                  }
              }
              return result;
          }
      }
      
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章