数据结构之二叉树的遍历
-
先序遍历(PreOrder):若二叉树非空,则先访问根节点,再访问左子树,最后访问右子树。
-
中序遍历(InOrder):若二叉树非空,则先访问左子树,再访问根节点,最后访问右子树。
-
后序遍历(PostOder):若二叉树非空,则先访问左子树,再访问右子树,最后访问根节点。
节点结构如下:
1 /** 2 * 二叉树节点结构 3 * Created by Administrator on 2017/5/2 0002. 4 */ 5 public class TreeNode { 6 public int val; 7 public TreeNode left; 8 public TreeNode right; 9 public TreeNode(int x){ 10 this.val = x; 11 } 12 }
自定义节点处理函数:
1 /*对每个节点进行处理*/ 2 public static void process(int v){ 3 System.out.println(v); 4 }
1 /*递归形式*/ 2 public static void preOrder(TreeNode root){ 3 if(root == null){ 4 return; 5 } 6 process(root.val); 7 preOrder(root.left); 8 preOrder(root.right); 9 }
1 //非递归形式,借助栈 2 public static void preOrder2(TreeNode root) { 3 4 if (root == null) { 5 return; 6 } 7 8 Stack<TreeNode> stack = new Stack<>(); 9 10 while (root != null || !stack.isEmpty()) { 11 while (root != null) { 12 print(root.val); 13 stack.push(root); 14 root = root.left; 15 } 16 17 if (!stack.isEmpty()) { 18 root = stack.peek(); 19 stack.pop(); 20 root = root.right; 21 } 22 } 23 }
1 /*递归形式*/ 2 public static void inOrder(TreeNode root){ 3 if(root == null){ 4 return; 5 } 6 if(root.left != null){ 7 inOrder(root.left); 8 } 9 process(root.val); 10 if(root.right != null){ 11 inOrder(root.right); 12 } 13 }
1 /*非递归形式*/ 2 public static void inOrder(TreeNode root){ 3 if(root == null){ 4 return; 5 } 6 Stack<TreeNode> st = new Stack<TreeNode>(); 7 st.push(root); 8 TreeNode tmp; 9 while (!st.empty()){ 10 tmp = st.peek(); 11 while (tmp != null){ 12 st.push(tmp.left); 13 tmp = tmp.left; 14 } 15 if(tmp == null){ 16 st.pop(); 17 } 18 if(!st.empty()) { 19 tmp = st.pop(); 20 process(tmp.val); 21 st.push(tmp.right); 22 } 23 } 24 }
1 /*递归形式*/ 2 public static void postOrder(TreeNode root){ 3 if(root == null){ 4 return; 5 } 6 if(root.left != null){ 7 postOrder(root.left); 8 } 9 if(root.right != null){ 10 postOrder(root.right); 11 } 12 process(root.val); 13 }
1 /*后序非递归形式*/ 2 public static void postOrder(TreeNode root){ 3 if (root == null) { 4 return; 5 } 6 7 Stack<TreeNode> stack = new Stack<>(); 8 TreeNode node = root; 9 //最后访问的节点 10 TreeNode lastVisit = root; 11 while (node != null || !stack.isEmpty()) { 12 13 //左子树入栈 14 while (node != null) { 15 stack.push(node); 16 node = node.left; 17 } 18 19 //查看当前栈顶元素 20 node = stack.peek(); 21 22 //如果其右子树也为空,或者右子树已经访问 23 //则可以直接输出当前节点的值 24 if (node.right == null || node.right == lastVisit) { 25 print(node.val); 26 stack.pop(); 27 lastVisit = node; 28 node = null; 29 } else { 30 //否则遍历右子树 31 node = node.right; 32 } 33 } 34 }