1. 程式人生 > >二叉搜尋樹Java實現(查詢、插入、刪除、遍歷)

二叉搜尋樹Java實現(查詢、插入、刪除、遍歷)

複製程式碼
  1 class Node {
  2     int key;
  3     int value;
  4     Node leftChild;
  5     Node rightChild;
  6 
  7     public Node(int key, int value) {
  8         this.key = key;
  9         this.value = value;
 10     }
 11 
 12     public void displayNode() {
 13 
 14     }
 15 }
 16 
 17 class Tree {
18 Node root; 19 20 public Node find(int key) { 21 Node currentNode = root; 22 while (currentNode != null && currentNode.key != key) { 23 if (key < currentNode.key) { 24 currentNode = currentNode.leftChild; 25 } else {
26 currentNode = currentNode.rightChild; 27 } 28 } 29 return currentNode; 30 } 31 32 public void insert(int key, int value) { 33 if (root == null) { 34 root = new Node(key, value); 35 return; 36 }
37 Node currentNode = root; 38 Node parentNode = root; 39 boolean isLeftChild = true; 40 while (currentNode != null) { 41 parentNode = currentNode; 42 if (key < currentNode.key) { 43 currentNode = currentNode.leftChild; 44 isLeftChild = true; 45 } else { 46 currentNode = currentNode.rightChild; 47 isLeftChild = false; 48 } 49 } 50 Node newNode = new Node(key, value); 51 if (isLeftChild) { 52 parentNode.leftChild = newNode; 53 } else { 54 parentNode.rightChild = newNode; 55 } 56 } 57 58 public boolean delete(int key) { 59 Node currentNode = root; 60 Node parentNode = root; 61 boolean isLeftChild = true; 62 while (currentNode != null && currentNode.key != key) { 63 parentNode = currentNode; 64 if (key < currentNode.key) { 65 currentNode = currentNode.leftChild; 66 isLeftChild = true; 67 } else { 68 currentNode = currentNode.rightChild; 69 isLeftChild = false; 70 } 71 } 72 if (currentNode == null) { 73 return false; 74 } 75 if (currentNode.leftChild == null && currentNode.rightChild == null) { 76 //要刪除的節點為葉子節點 77 if (currentNode == root) 78 root = null; 79 else if (isLeftChild) 80 parentNode.leftChild = null; 81 else 82 parentNode.rightChild = null; 83 } else if (currentNode.rightChild == null) {//要刪除的節點只有左孩子 84 if (currentNode == root) 85 root = currentNode.leftChild; 86 else if (isLeftChild) 87 parentNode.leftChild = currentNode.leftChild; 88 else 89 parentNode.rightChild = currentNode.leftChild; 90 } else if (currentNode.leftChild == null) {//要刪除的節點只有右孩子 91 if (currentNode == root) 92 root = currentNode.rightChild; 93 else if (isLeftChild) 94 parentNode.leftChild = currentNode.rightChild; 95 else 96 parentNode.rightChild = currentNode.rightChild; 97 } else { //要刪除的節點既有左孩子又有右孩子 98 //思路:用待刪除節點右子樹中的key值最小節點的值來替代要刪除的節點的值,然後刪除右子樹中key值最小的節點 99 //右子樹key最小的節點一定不含左子樹,所以刪除這個key最小的節點一定是屬於葉子節點或者只有右子樹的節點 100 Node directPostNode = getDirectPostNode(currentNode); 101 currentNode.key = directPostNode.key; 102 currentNode.value = directPostNode.value; 103 } 104 return true; 105 } 106 107 private Node getDirectPostNode(Node delNode) {//方法作用為得到待刪除節點的直接後繼節點 108 109 Node parentNode = delNode;//用來儲存待刪除節點的直接後繼節點的父親節點 110 Node direcrPostNode = delNode;//用來儲存待刪除節點的直接後繼節點 111 Node currentNode = delNode.rightChild; 112 while (currentNode != null) { 113 parentNode = direcrPostNode; 114 direcrPostNode = currentNode; 115 currentNode = currentNode.leftChild; 116 } 117 if (direcrPostNode != delNode.rightChild) {//從樹中刪除此直接後繼節點 118 parentNode.leftChild = direcrPostNode.rightChild; 119 direcrPostNode.rightChild = null; 120 } 121 return direcrPostNode;//返回此直接後繼節點 122 123 } 124 125 public void preOrder(Node rootNode) { 126 if (rootNode != null) { 127 System.out.println(rootNode.key + " " + rootNode.value); 128 preOrder(rootNode.leftChild); 129 preOrder(rootNode.rightChild); 130 } 131 } 132 133 public void inOrder(Node rootNode) { 134 if (rootNode != null) { 135 inOrder(rootNode.leftChild); 136 System.out.println("key: " + rootNode.key + " " + "value: " + rootNode.value); 137 inOrder(rootNode.rightChild); 138 } 139 } 140 141 public void postOrder(Node rootNode) { 142 if (rootNode != null) { 143 postOrder(rootNode.leftChild); 144 postOrder(rootNode.rightChild); 145 System.out.println(rootNode.key + " " + rootNode.value); 146 } 147 }
    
      private void destroy(Node tree) {
           if (tree==null)
               return ;
 
           if (tree.left != null)
               destroy(tree.leftChild);
           if (tree.right != null)
               destroy(tree.rightChild);
 
          tree=null;
      }
    
    public void destory() {
      destory(root);
    }
148 } 
149 public class BinarySearchTreeApp {
150   public static void main(String[] args) {
151       Tree tree = new Tree();
152     tree.insert(6, 6);//插入操作,構造圖一所示的二叉樹

153     tree.insert(3, 3);

154     tree.insert(14, 14);

155     tree.insert(16, 16);

156     tree.insert(10, 10);

157     tree.insert(9, 9);

158     tree.insert(13, 13);

159     tree.insert(11, 11);

160     tree.insert(12, 12);

161 162   System.out.println("刪除前遍歷結果");

163     tree.inOrder(tree.root);//中序遍歷操作

164 165   System.out.println("刪除節點10之後遍歷結果");

166     tree.delete(10);//刪除操作

167     tree.inOrder(tree.root); 168
    }

169 }
複製程式碼