這裏使用下圖的二叉樹作爲例子:
首先建立樹這個類:
public class Node { private int data; private Node leftNode; private Node rightNode; public Node(int data, Node leftNode, Node rightNode) { this.data = data; this.leftNode = leftNode; this.rightNode = rightNode; } public int getData() { return data; } public void setData(int data) { this.data = data; } public Node getLeftNode() { return leftNode; } public void setLeftNode(Node leftNode) { this.leftNode = leftNode; } public Node getRightNode() { return rightNode; } public void setRightNode(Node rightNode) { this.rightNode = rightNode; } }
使用遞歸的方式遍歷二叉樹,這種遍歷雖然比較簡單,但涉及到遞歸的算法都儘量慎用!
//遞歸遍歷二叉樹 public class RecursionBinaryTree { //先建立子節點,再建立父節點 public Node init(){ Node E = new Node(8,null,null); Node C = new Node(6,E,null); Node D = new Node(3,null,null); Node B = new Node(2,D,null); Node A = new Node(7, B, C); return A; //返回根節點 } public void printNode(Node node){ System.out.print(node.getData()); } //先序遍歷:根左右的順序遍歷二叉樹 public void firstTraversal(Node root){ printNode(root); //輸出根節點數據 if(root.getLeftNode()!=null){ firstTraversal(root.getLeftNode()); } if(root.getRightNode()!=null){ firstTraversal(root.getRightNode()); } } //中序遍歷:左根右 public void inOrderTraversal(Node root){ if(root.getLeftNode()!=null){ inOrderTraversal(root.getLeftNode()); } printNode(root); if(root.getRightNode()!=null){ inOrderTraversal(root.getRightNode()); } } //後序遍歷:左右根 public void postOrderTraversal(Node root){ if(root.getLeftNode()!=null){ postOrderTraversal(root.getLeftNode()); } if(root.getRightNode()!=null){ postOrderTraversal(root.getRightNode()); } printNode(root); } public static void main(String[] args) { RecursionBinaryTree tree = new RecursionBinaryTree(); Node root = tree.init(); System.out.println("先序遍歷:"); tree.firstTraversal(root); System.out.println(); System.out.println("中序遍歷:"); tree.inOrderTraversal(root); System.out.println(); System.out.println("後序遍歷:"); tree.postOrderTraversal(root); } }
再看看使用非遞歸的方式遍歷二叉樹,面試的時候會經常問到使用非遞歸的方式實現二叉樹的中序遍歷。
//堆棧遍歷二叉樹 public class StackBinaryTree { public Node init(){ Node E = new Node(8,null,null); Node C = new Node(6,E,null); Node D = new Node(3,null,null); Node B = new Node(2,D,null); Node A = new Node(5, B, C); return A; //返回根節點 } public void printNode(Node node){ System.out.print(node.getData()); } //先序遍歷:根左右 public void firstTraversal(Node root){ Stack<Node> stack = new Stack<>(); //定義一個棧 while (root!=null||stack.size()>0){ //判斷節點是否爲空或者棧中是否爲空,當均爲空時,結束循環 if(root!=null){ printNode(root); stack.push(root); root = root.getLeftNode(); }else { root = stack.pop(); root = root.getRightNode(); } } } //中序遍歷:左根右 public void inOrderTraversal(Node root){ Stack<Node> stack = new Stack<>(); //定義一個棧 while (root!=null||stack.size()>0){ if(root!=null){ stack.push(root); //直接壓入棧 root = root.getLeftNode(); }else { root = stack.pop(); //出棧時輸出下 printNode(root); root = root.getRightNode(); } } } public void postOrderTraversal(Node root){ Stack<Node> stack = new Stack<>(); Stack<Node> output = new Stack<>();//構造一箇中間棧存儲後序遍歷的結果 while (root!=null||stack.size()>0){ if(root!=null){ output.push(root); stack.push(root); root = root.getRightNode(); }else { root = stack.pop(); root = root.getLeftNode(); } } while (output.size()>0){ printNode(output.pop()); } } public static void main(String[] args) { StackBinaryTree tree = new StackBinaryTree(); Node root = tree.init(); System.out.println("先序遍歷:"); tree.firstTraversal(root); System.out.println("中序遍歷:"); tree.inOrderTraversal(root); System.out.println("後序遍歷:"); tree.postOrderTraversal(root); } }