/** * 二叉樹的定義和遍歷 */ public class BinaryTree { /** * 打印節點的信息 */ public void printNode(TreeNode<String> node){ System.out.print(node.getData()+" "); } /** * 遞歸先序遍歷二叉樹 */ public void preIterator(TreeNode<String> node){ this.printNode(node); if (node.getLefNode() != null) { this.preIterator(node.getLefNode()); } if (node.getRigNode() != null) { this.preIterator(node.getRigNode()); } } /** * 遞歸中序遍歷二叉樹 */ public void midIterator(TreeNode<String> node){ if (node.getLefNode() != null) { midIterator(node.getLefNode()); } this.printNode(node); if (node.getRigNode() != null) { midIterator(node.getRigNode()); } } /** * 遞歸後續遍歷二叉樹 */ public void lasIterator(TreeNode<String> node){ if (node.getLefNode() != null) { this.lasIterator(node.getLefNode()); } if (node.getRigNode() != null) { this.lasIterator(node.getRigNode()); } this.printNode(node); } /** * 非遞歸先序遍歷二叉樹 * @return */ public void noDiGuiPreIterator(TreeNode<String> node) { Stack<TreeNode<String>> stack = new Stack<>(); TreeNode<String> p = node; while (p != null || stack.size() > 0) { while(p != null){ //壓入全部的左節點,壓入前訪問它。左節點壓入完後pop訪問右節點。 this.printNode(p); stack.push(p); p = p.getLefNode(); } if(stack.size() > 0){ p = stack.pop(); p = p.getRigNode(); } } } /** * 非遞歸中序遍歷二叉樹 * @return */ public void noDiGuiMidIterator(TreeNode<String> node){ Stack<TreeNode<String>> stack = new Stack<>(); TreeNode<String> p = node; while (p != null || stack.size() > 0) { while(p != null){ stack.push(p); p = p.getLefNode(); } if(stack.size() > 0){ p = stack.pop(); this.printNode(p); p = p.getRigNode(); } } } /** * 非遞歸後續遍歷二叉樹 * @return */ public void noDiGuiLasIterator(TreeNode<String> node){ Stack<TreeNode<String>> stack = new Stack<>(); TreeNode<String> p = node; TreeNode<String> prev = node; while (p != null || stack.size() > 0) { while (p != null) { stack.push(p); p = p.getLefNode(); } if (stack.size() > 0) { TreeNode<String> temp = stack.peek().getRigNode(); if (temp == null || temp == prev) { p = stack.pop(); this.printNode(p); prev = p; p = null; } else { p = temp; } } } } /** * 不只是二叉樹,其餘的多叉數也適合 * 深度優先遍歷 */ public void depthOrderTraversal(TreeNode<String> node){ Stack<TreeNode<String>> stack=new Stack<>(); if (node != null){ stack.push(node); } while(stack.isEmpty()==false){ TreeNode<String> p = stack.pop(); this.printNode(p); //棧是後進先出,由於先遍歷左節點,全部左節點要後添加,即先添加右節點。 if(p.getRigNode() != null){ stack.push(p.getRigNode()); } if(p.getLefNode() != null){ stack.push(p.getLefNode()); } } System.out.print("\n"); } /** * 不只適合二叉樹,也適合其餘的多叉樹 * 廣度優先遍歷 */ public void levelOrderTraversal(TreeNode<String> node){ Queue<TreeNode<String>> queue=new ArrayDeque<>(); queue.add(node); while(queue.isEmpty()==false){ TreeNode<String> p = queue.remove(); this.printNode(p); //隊列是先進先出,全部先放左子樹,先遍歷左邊的節點 if(p.getLefNode() != null){ queue.add(p.getLefNode()); } if(p.getRigNode() != null){ queue.add(p.getRigNode()); } } } // 初始化二叉樹 public TreeNode<String> init() { TreeNode<String> D = new TreeNode<String>("D", null, null); TreeNode<String> H = new TreeNode<String>("H", null, null); TreeNode<String> I = new TreeNode<String>("I", null, null); TreeNode<String> J = new TreeNode<String>("J", null, null); TreeNode<String> P = new TreeNode<String>("P", null, null); TreeNode<String> G = new TreeNode<String>("G", P, null); TreeNode<String> F = new TreeNode<String>("F", null, J); TreeNode<String> E = new TreeNode<String>("E", H, I); TreeNode<String> B = new TreeNode<String>("B", D, E); TreeNode<String> C = new TreeNode<String>("C", F, G); TreeNode<String> A = new TreeNode<String>("A", B, C); return A; } /** * 測試 * @param args */ public static void main(String[] args) { BinaryTree binaryTree = new BinaryTree(); TreeNode<String> node = binaryTree.init(); System.out.println("二叉樹的遞歸先序遍歷"); binaryTree.preIterator(node); System.out.println("\n二叉樹的非遞歸先序遍歷"); binaryTree.noDiGuiPreIterator(node); System.out.println("\n二叉樹的遞歸中序遍歷"); binaryTree.midIterator(node); System.out.println("\n二叉樹的非遞歸中序遍歷"); binaryTree.noDiGuiMidIterator(node); System.out.println("\n二叉樹的遞歸後序遍歷"); binaryTree.lasIterator(node); System.out.println("\n二叉樹的非遞歸後序遍歷"); binaryTree.noDiGuiLasIterator(node); System.out.println("\n數的深度優先遍歷"); binaryTree.depthOrderTraversal(node); System.out.println("\n數的廣度優先遍歷"); binaryTree.levelOrderTraversal(node); } } /** * 定義節點 */ class TreeNode<T>{ private T data; private TreeNode<T> lefNode; private TreeNode<T> rigNode; public TreeNode(T data, TreeNode<T> lefNode, TreeNode<T> rigNode) { super(); this.data = data; this.lefNode = lefNode; this.rigNode = rigNode; } public T getData() { return data; } public void setData(T data) { this.data = data; } public TreeNode<T> getLefNode() { return lefNode; } public void setLefNode(TreeNode<T> lefNode) { this.lefNode = lefNode; } public TreeNode<T> getRigNode() { return rigNode; } public void setRigNode(TreeNode<T> rigNode) { this.rigNode = rigNode; } }
結果:java
二叉樹的遞歸先序遍歷
A B D E H I C F J G P
二叉樹的非遞歸先序遍歷
A B D E H I C F J G P
二叉樹的遞歸中序遍歷
D B H E I A F J C P G
二叉樹的非遞歸中序遍歷
D B H E I A F J C P G
二叉樹的遞歸後序遍歷
D H I E B J F P G C A
二叉樹的非遞歸後序遍歷
D H I E B J F P G C A
數的深度優先遍歷
A B D E H I C F J G P node
數的廣度優先遍歷
A B C D E F G H I J P 測試