二叉樹前序中序後序查詢
阿新 • • 發佈:2021-08-09
13.1.1 二叉樹-查詢指定節點
要求:
- 請編寫前序查詢,中序查詢和後序查詢
- 並分別使用三種查詢方式,查詢Node的id = 5 的節點
- 並分析各種查詢方式,分別比較了多少次
思路:
-
前序查詢:
- 先判斷當前節點的id是否是要查詢的
- 如果相等,則返回當前節點
- 如果不相等,則判斷當前節點的左節點是否為空,如果不為空,則遞迴前序查詢
- 如果左遞迴前序查詢,找到節點則返回,否則判斷,當前的節點的右子節點是否為空,如果不空,則繼續向右遞迴前序查詢
-
中序查詢
- 判斷當前節點的左節點是否為空,如果不為空,則遞迴中序查詢
- 如果找到,則返回,如果沒找到,就和當前節點比較,找到則返回
- 如果當前節點不相等,則判斷右節點是否為空,如果不為空,則遞迴中序查詢右子樹,找到則返回
- 如果右遞迴中序查詢沒找到就返回null
-
後續查詢
- 判斷當前節點的左節點是否為空,如果不為空則進行左遞迴
- 如果為空,則判斷右節點是否為空,如果不為空則進行右遞迴
- 如果為空,則判斷當前節點是否相等,如果相等則返回,如果不相等則返回null
package tree; public class BinaryTreeDemo { public static void main(String[] args) { // 建立二叉樹 BinaryTree binaryTree = new BinaryTree(); // 建立需要的節點 Node1 root = new Node1(1,"a1"); Node1 n2 = new Node1(2,"a2"); Node1 n3 = new Node1(3,"a3"); Node1 n4 = new Node1(4,"a4"); // 說明,我們先手動建立二叉樹,後面使用遞迴建立二叉樹 root.setLeft(n2); root.setRight(n3); n3.setRight(n4); binaryTree.setRoot(root); // 測試 遍歷 System.out.println("前序遍歷:"); binaryTree.preOrder(); // 1 2 3 4 System.out.println("中序遍歷 "); binaryTree.infixOrder(); // 2 1 3 4 System.out.println("後序遍歷:"); binaryTree.postOrder(); // 2 4 3 1 // 測試查詢 System.out.println("前序查詢");// 前序遍歷的次數 4 Node1 resNode = binaryTree.preOrderSearch(4); if (resNode != null){ System.out.println("finded\t"+resNode.getId() + "\t" + resNode.getName()); }else{ System.out.println("Not find"); } System.out.println("中序查詢"); // 中序遍歷次數 3 resNode = binaryTree.infixOrderSearch(4); if (resNode != null){ System.out.println("finded\t"+resNode.getId() + "\t" + resNode.getName()); }else{ System.out.println("Not find"); } System.out.println("後序查詢"); // 後序遍歷 2 resNode = binaryTree.postOrderSearch(4); if (resNode != null){ System.out.println("finded\t"+resNode.getId() + "\t" + resNode.getName()); }else{ System.out.println("Not find"); } } } class BinaryTree{ private Node1 root; public Node1 getRoot() { return root; } public void setRoot(Node1 root) { this.root = root; } // 前序遍歷 public void preOrder(){ if (this.root != null){ this.root.preOrder(); }else{ System.out.println("二叉樹為空"); } } // 中序遍歷 public void infixOrder(){ if (this.root != null){ this.root.infixOrder(); }else{ System.out.println("二叉樹為空"); } } // 後序遍歷 public void postOrder(){ if (this.root != null){ this.root.postOrder(); }else{ System.out.println("二叉樹為空"); } } // 前序查詢 public Node1 preOrderSearch(int id){ if (this.root != null){ return root.preOrdersearch(id); }else{ return null; } } // 中序查詢 public Node1 infixOrderSearch(int id){ if (this.root != null){ return root.infixOrderSearch(id); }else { return null; } } // 後序查詢 public Node1 postOrderSearch(int id){ if (this.root != null){ return root.postOrderSearch(id); } else{ return null; } } } // 先建立節點 class Node1{ private int id; private String name; private Node1 left; private Node1 right; public Node1(int id, String name) { this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Node1 getLeft() { return left; } public void setLeft(Node1 left) { this.left = left; } public Node1 getRight() { return right; } public void setRight(Node1 right) { this.right = right; } @Override public String toString() { return "Node1{" + "id=" + id + ", name='" + name + '\'' + '}'; } // 編寫前序遍歷 public void preOrder(){ System.out.println(this); // 先輸出當前節點 // 遞歸向左子樹前序遍歷 if (this.left != null){ this.left.preOrder(); } // 遞歸向右子樹前序遍歷 if (this.right != null){ this.right.preOrder(); } } // 編寫中序遍歷 public void infixOrder(){ // 遞歸向左子樹中序遍歷 if (this.left != null){ this.left.infixOrder(); } System.out.println(this); // 嘀咕向右子樹中序遍歷 if (this.right != null){ this.right.infixOrder(); } } // 編寫後序遍歷 public void postOrder(){ // 左子樹後序遍歷 if (this.left != null){ this.left.postOrder(); } // 右子樹後序遍歷 if (this.right != null){ this.right.postOrder(); } System.out.println(this); } // 前序遍歷查詢 /** * * @param id 要查詢的id * @return 若找到則返回當前Node1,如果沒找到則返回null */ public Node1 preOrdersearch(int id){ System.out.println("進行前序遍歷~~"); // 用來判斷比較幾次 // 比較當前節點是不是 if (this.id == id){ return this; } // 判斷當前節點的左子樹是否為空 Node1 resNode = null; // 通過res判斷找沒找到 if (this.left != null){ resNode = this.left.preOrdersearch(id); } if (resNode != null){ // 說明我們左子樹找到了 return resNode; } // 判斷當前節點的右子樹是否為空 if (this.right != null){ resNode = this.right.preOrdersearch(id); } if (resNode != null){ return resNode; } return resNode; } // 中序查詢 public Node1 infixOrderSearch(int id){ Node1 resNode = null; // 判斷左節點是否為空,如果不為空則便利左節點 if (this.left != null){ resNode = this.left.infixOrderSearch(id); } if (resNode != null){ return resNode; } System.out.println("進行中序遍歷~~"); // 用來判斷比較幾次 // 判斷當前節點是否是要找的節點,如果是則返回 if (this.id == id){ return this; } // 判斷右子樹是否為空,如果不為空,則進行右遍歷 if (this.right != null){ resNode = this.right.infixOrderSearch(id); } if (resNode != null){ return resNode; } return resNode; } // 逆序查詢 public Node1 postOrderSearch(int id){ Node1 resNode = null; // 判斷左子樹是否為空,如果不為空,則進行左遞迴 if (this.left != null){ resNode = this.left.postOrderSearch(id); } if (resNode != null){ return resNode; } // 判斷右子樹是否為空,如果不為空,則進行右遞迴 if (this.right != null){ resNode = this.right.postOrderSearch(id); } if (resNode != null){ return resNode; } System.out.println("進行後序遍歷~~"); // 用來判斷比較幾次 // 判斷當前節點是否是要找的節點,如果是,則直接返回 if (this.id == id){ return this; } return resNode; } }