直接上代碼呵呵,裏面有註解java
package www.com.leetcode.specificProblem; import java.util.ArrayList; import java.util.List; import java.util.Stack; /** * 總結了三種非遞歸遍歷二叉樹 * @author 85060 * */ public class TraverseBinaryTree { //用來裝遍歷序列的一個list,展現的時候用 private List<TreeNode> helpList = new ArrayList<>(); public static void main(String[] args) { TreeNode root = createATree(); TraverseBinaryTree traverseBinaryTree = new TraverseBinaryTree(); //traverseBinaryTree.frontTraverseRecursion(root); //traverseBinaryTree.midTraverseRecursion(root); traverseBinaryTree.backTraverseRecursion(root); String rightAnswer = traverseBinaryTree.helpList.toString(); System.out.println("right: " + rightAnswer); traverseBinaryTree.helpList.clear(); //traverseBinaryTree.frontTravese(root); //traverseBinaryTree.midTraverse(root); traverseBinaryTree.backTraverse(root); String myAnswer = traverseBinaryTree.helpList.toString(); System.out.println("my ans: " + myAnswer); System.out.println("bingo? " + rightAnswer.equals(myAnswer)); } /** * 遞歸版的前序遍歷二叉樹 * @param node */ private void frontTraverseRecursion(TreeNode node) { if(node == null)return; helpList.add(node); frontTraverseRecursion(node.left); frontTraverseRecursion(node.right); } /** * 遞歸式的中序遞歸二叉樹 * @param node */ private void midTraverseRecursion(TreeNode node) { if(node == null)return; midTraverseRecursion(node.left); helpList.add(node); midTraverseRecursion(node.right); } /** * 遞歸式的後序遍歷二叉樹 * @param node */ private void backTraverseRecursion(TreeNode node) { if(node == null)return; backTraverseRecursion(node.left); backTraverseRecursion(node.right); helpList.add(node); } /** * 非遞歸的前序遍歷二叉樹 * 用一個node,一直往左遍歷,一邊遍歷一邊入棧,當走到左邊的盡頭後,就出棧,而後去這個出棧元素的右子樹,繼續循環 * @param root */ private void frontTravese(TreeNode root) { if(root == null)return; Stack<TreeNode> stack = new Stack<TreeNode>(); TreeNode node = root; while(node != null || !stack.isEmpty()) { if(node != null) { helpList.add(node);//visit stack.push(node); node = node.left; } else { //左子樹沒了,進入棧中而後去右子樹咯 node = stack.pop().right; } } } /** * 非遞歸式的中序遞歸二叉樹 * @param root */ private void midTraverse(TreeNode root) { if(root == null)return ; Stack<TreeNode> stack = new Stack<TreeNode>(); TreeNode node = root; while(node != null || !stack.isEmpty()) { while(node != null) {//一直往左走到盡頭 stack.push(node); node = node.left; } if(!stack.isEmpty()) { node = stack.pop(); helpList.add(node);//visit node = node.right;//進入右子樹 } } } /** * 非遞歸的後序遍歷二叉樹 * 後序遍歷的關鍵就是要判斷上一個結點的右孩子訪問了沒,因此要存上次訪問的結點 * @param root */ private void backTraverse(TreeNode root) { if(root == null)return; Stack<TreeNode> stack = new Stack<TreeNode>(); TreeNode node = root; TreeNode lastVisit = null;//記錄剛剛訪問過的那個結點,用來區分stack中pop出來的結點的右子樹訪問過沒 while(node != null || !stack.isEmpty()) { while(node != null) {//一直走到樹的最左邊,stack是最左邊的那個葉子結點 stack.push(node); node = node.left; } while(!stack.isEmpty()) { node = stack.peek(); if(node.right == null || node.right == lastVisit) {//沒有右子樹,右子樹訪問過了,均可以訪問這個結點了 helpList.add(node);//visit //System.out.println(node); lastVisit = node; stack.pop(); if(stack.isEmpty())return;//這個很重要,否則會無限循環 } else {//右子樹不爲空,並且沒訪問過 node = node.right; break;//出去要走到這個右子樹的最左邊噢 } } } } /** * 構造一顆測試用的二叉樹數據 * @return */ private static TreeNode createATree() { TreeNode root = new TreeNode(4); root.left = new TreeNode(3); root.right = new TreeNode(6); root.left.left = new TreeNode(11); root.left.right = new TreeNode(12); root.left.right.left = new TreeNode(45); root.right.left = new TreeNode(13); root.right.right = new TreeNode(14); root.right.right.right = new TreeNode(32); return root; } } /** * 二叉樹結點類 * @author 85060 * */ class TreeNode { int data; TreeNode left; TreeNode right; public TreeNode(int data) { this.data = data; } @Override public String toString() { // TODO Auto-generated method stub return data + ""; } }