【使用遞歸和非遞歸實現二叉搜索樹的遍歷】
使用遞歸和非遞歸實現二叉搜索樹的遍歷
1.遍歷的基本概念:所謂遍歷(Traversal),是指沿着某條搜索路線,依次對樹中每個結點均做一次且僅做一次訪問。訪問結點所做的操作依賴於具體的應用問題。 遍歷是二叉樹上最重要的運算之一,是二叉樹上進行其它運算之基礎。
2.使用遞歸算法分別執行先序,中序,后序遍歷:
1 public class BinaryTree { 2 // 初始化二叉樹 3 public Node init() { 4 Node I = new Node(8, null, null); 5 Node H = new Node(4, null, null); 6 Node G = new Node(2, null, null); 7 Node F = new Node(7, null, I); 8 Node E = new Node(5, H, null); 9 Node D = new Node(1, null, G); 10 Node C = new Node(9, F, null); 11 Node B = new Node(3, D, E); 12 Node A = new Node(6, B, C); 13 // 返回根節點 14 return A; 15 } 16 17 // 訪問節點 18 public void printNode(Node node) { 19 System.out.println(node.getData()); 20 } 21 22 // 先序遍歷 23 public void theFirstTraversal(Node root) { 24 printNode(root); 25 // 使用遞歸遍歷左孩子 26 if (root.getLeftNode() != null) { 27 theFirstTraversal(root.getLeftNode()); 28 } 29 // 使用遞歸遍歷右孩子 30 if (root.getRightNode() != null) { 31 theFirstTraversal(root.getRightNode()); 32 } 33 } 34 35 // 中序遍歷 36 public void theInOrderTraversal(Node root) { 37 // 遞歸遍歷左孩子 38 if (root.getLeftNode() != null) { 39 theInOrderTraversal(root.getLeftNode()); 40 } 41 printNode(root); 42 // 遍歷右孩子 43 if (root.getRightNode() != null) { 44 theInOrderTraversal(root.getRightNode()); 45 } 46 } 47 48 // 后序遍歷 49 public void thePostOrderTraveral(Node root) { 50 // 遞歸遍歷左孩子 51 if (root.getLeftNode() != null) { 52 theInOrderTraversal(root.getLeftNode()); 53 } 54 55 // 遍歷右孩子 56 if (root.getRightNode() != null) { 57 theInOrderTraversal(root.getRightNode()); 58 } 59 printNode(root); 60 61 } 62 63 public static void main(String[] args) { 64 BinaryTree t = new BinaryTree(); 65 Node node = t.init(); 66 System.out.println("先序遍歷:"); 67 t.theFirstTraversal(node); 68 System.out.println("中序遍歷:"); 69 t.theInOrderTraversal(node); 70 System.out.println("后序遍歷:"); 71 t.thePostOrderTraveral(node); 72 73 } 74 75 }
2.使用非遞歸算法分別執行先序,中序,后序遍歷:
1 public class BinaryTree1 { 2 // 初始化二叉樹 3 public Node init() { 4 Node I = new Node(8, null, null); 5 Node H = new Node(4, null, null); 6 Node G = new Node(2, null, null); 7 Node F = new Node(7, null, I); 8 Node E = new Node(5, H, null); 9 Node D = new Node(1, null, G); 10 Node C = new Node(9, F, null); 11 Node B = new Node(3, D, E); 12 Node A = new Node(6, B, C); 13 // 返回根節點 14 return A; 15 } 16 17 public void printNode(Node node) { 18 System.out.print(node.getData()); 19 } 20 21 public void theFirstTraversal_Stack(Node root) { // 先序遍歷 22 Stack<Node> stack = new Stack<Node>(); 23 Node node = root; 24 while (node != null || stack.size() > 0) { // 將所有左孩子壓棧 25 if (node != null) { // 壓棧之前先訪問 26 printNode(node); 27 28 stack.push(node); 29 30 node = node.getLeftNode(); 31 32 } else { 33 node = stack.pop(); 34 35 node = node.getRightNode(); 36 37 } 38 } 39 } 40 41 public void theInOrderTraversal_Stack(Node root) { // 中序遍歷 42 Stack<Node> stack = new Stack<Node>(); 43 Node node = root; 44 while (node != null || stack.size() > 0) { 45 if (node != null) { 46 stack.push(node); // 直接壓棧 47 node = node.getLeftNode(); 48 } else { 49 node = stack.pop(); // 出棧並訪問 50 printNode(node); 51 node = node.getRightNode(); 52 } 53 } 54 } 55 56 public void thePostOrderTraversal_Stack(Node root) { // 后序遍歷 57 Stack<Node> stack = new Stack<Node>(); 58 Stack<Node> output = new Stack<Node>();// 構造一個中間棧來存儲逆后序遍歷的結果 59 Node node = root; 60 while (node != null || stack.size() > 0) { 61 if (node != null) { 62 output.push(node); 63 64 stack.push(node); 65 66 node = node.getRightNode(); 67 68 } else { 69 node = stack.pop(); 70 node = node.getLeftNode(); 71 } 72 } 73 System.out.println(output.size()); 74 while (output.size() > 0) { 75 76 printNode(output.pop()); 77 } 78 } 79 80 public static void main(String[] args) { 81 BinaryTree1 tree = new BinaryTree1(); 82 Node root = tree.init(); 83 System.out.println("先序遍歷"); 84 tree.theFirstTraversal_Stack(root); 85 System.out.println(""); 86 System.out.println("中序遍歷"); 87 tree.theInOrderTraversal_Stack(root); 88 System.out.println(""); 89 System.out.println("后序遍歷"); 90 tree.thePostOrderTraversal_Stack(root); 91 92 } 93 }
