一些概念:
二叉查找樹的重要性質:對於樹中的每一個節點X,它的左子樹任一節點的值均小於X,右子樹上任意節點的值均大於X.
二叉查找樹是java的TreeSet和TreeMap類實現的基礎.
由於樹的遞歸定義,二叉查找樹的代碼實現也基本上都是使用遞歸的函數,二叉查找樹的平均深度是O(logN).
因為二叉查找樹要求所有的節點都可以進行排序.所以編寫時代碼時需要一個Comparable泛型接口,當需要對類中的對象進行排序的時候,就需要實現這個泛型接口,里邊定義了一個public int compareTo(Object o)方法,接受一個Object作為參數,java中String,Integer等類都實現了這個接口.
java代碼實現:
remove方法:在查找樹的代碼實現中,最難得是刪除,因為這涉及到三種情況:
被刪除節點是樹葉節點(沒有子樹):最簡單,直接刪除,將該節點置為null即可
被刪除節點有一個子節點(左子樹或右子樹):是該節點的父節點指向該節點的子節點(左或右).見圖1
被刪除節點有兩個子節點:用其右子樹中的最小值代替該節點上的值,刪除其右子樹上的最小值.見圖2.

1 package com.wang.tree; 2 3 public class BinarySearchTree<T extends Comparable<T>>{ 4 5 6 private static class Node<T>{ 7 private T data; 8 private Node<T> left; 9 private Node<T> right; 10 11 public Node(T data){ 12 this(data,null,null); 13 } 14 public Node(T data, Node<T> left, Node<T> right) { 15 this.data = data; 16 this.left = left; 17 this.right = right; 18 } 19 } 20 21 //私有變量 根節點root 22 private Node<T> root; 23 24 //無參構造函數,根節點為null 25 public BinarySearchTree(){ 26 root=null; 27 } 28 29 //清空二叉查找樹 30 public void makeEmpty(){ 31 root=null; 32 } 33 //判斷樹是否為空 34 public boolean isEmpty(){ 35 36 return root==null; 37 } 38 //查找集合中是否有元素value,有返回true 39 public boolean contains(T value){ 40 41 return contains(value,root); 42 } 43 44 private boolean contains(T value, Node<T> t) { 45 46 if(t==null){ 47 return false; 48 } 49 int result=value.compareTo(t.data); 50 if(result<0){ 51 return contains(value,t.left); 52 }else if(result>0){ 53 return contains(value,t.right); 54 }else{ 55 return true; 56 } 57 } 58 59 //查找集合中的最小值 60 public T findMin(){ 61 62 return findMin(root).data; 63 } 64 private Node<T> findMin(Node<T> t) { 65 if(t==null){ 66 return null; 67 }else if(t.left==null){ 68 return t; 69 } 70 71 72 return findMin(t.left); 73 } 74 75 //查找集合中的最大值 76 public T findMax(){ 77 78 return findMax(root).data; 79 } 80 81 private Node<T> findMax(Node<T> t) { 82 if(t!=null){ 83 while(t.right!=null){ 84 t=t.right; 85 } 86 } 87 88 return t; 89 } 90 91 //插入元素 92 public void insert(T value){ 93 94 root =insert(value,root); 95 } 96 97 private Node<T> insert(T value, Node<T> t) { 98 if(t==null){ 99 return new Node(value,null,null); 100 } 101 int result=value.compareTo(t.data); 102 if(result<0){ 103 t.left=insert(value,t.left); 104 }else if(result>0){ 105 t.right=insert(value,t.right); 106 } 107 return t; 108 } 109 //移除元素 110 public void remove(T value){ 111 root=remove(value,root); 112 113 114 } 115 116 private Node<T> remove(T value, Node<T> t) { 117 if(t==null){ 118 return t; 119 } 120 121 int result=value.compareTo(t.data); 122 if(result<0){ 123 t.left=remove(value,t.left); 124 }else if(result>0){ 125 t.right=remove(value,t.right); 126 }else if(t.left!=null&&t.right!=null){//如果被刪除節點有兩個兒子 127 //1.當前節點值被其右子樹的最小值代替 128 t.data=findMin(t.right).data; 129 //將右子樹的最小值刪除 130 t.right=remove(t.data, t.right); 131 }else{ 132 //如果被刪除節點是一個葉子 或只有一個兒子 133 t=(t.left!=null)?t.left:t.right; 134 } 135 136 return t; 137 } 138 139 //中序遍歷打印 140 public void printTree(){ 141 printTree(root); 142 } 143 144 private void printTree(Node<T> t) { 145 146 if(t!=null){ 147 printTree(t.left); 148 System.out.println(t.data); 149 printTree(t.right); 150 } 151 } 152 }
測試代碼:
package com.wang.tree; public class TestBST { public static void main(String[] args) { BinarySearchTree<Integer> bst=new BinarySearchTree<>(); bst.insert(5); bst.insert(7); bst.insert(3); bst.insert(1); bst.insert(9); bst.insert(6); bst.insert(4); System.out.println("最小值:"+bst.findMin()); System.out.println("最大值:"+bst.findMax()); System.out.println("查找元素9是否存在:"+bst.contains(9)); System.out.println("查找元素8是否存在:"+bst.contains(8)); System.out.println("遍歷二叉樹"); bst.printTree(); } }
打印結果:
最小值:1
最大值:9
查找元素9是否存在:true
查找元素8是否存在:false
遍歷二叉樹
1
3
4
5
6
7
9
