1. 原理
二叉查找树,又称为二叉排序树、二叉搜索树。对于树中每一个节点X,它的左子树中所有项的值小于X中的项,而它的右子树中所有项的值大于X中的项。二叉查找树的平均深度为O(log N),搜索元素的时间复杂度也是O(log N)。是两种库集合类TreeSet、TreeMap实现的基础。
2. public API
void makeEmpty( ) --> 置空boolean isEmpty( ) --> 判空AnyType findMin( ) --> 寻找最小值AnyType findMax( ) --> 寻找最大值boolean contains( x ) --> 是否存在元素xvoid insert( x ) --> 插入元素xvoid remove( x ) --> 删除元素xvoid printTree( ) --> 遍历二叉树
3. 核心思想图解:递归
!寻找最小值
此处用递归实现:

!寻找最大值
此处用非递归实现,也可以用递归实现:

!是否存在元素x
从root开始往下找,找到含有项X的节点,则此操作返回true,没有找到则返回false。

!插入元素x
从root开始往下找到合适的插入位置,然后插入。

!删除元素x
从root开始往下找到元素x,找到则删除,并且处理好后续工作。

4. BinarySearchTree代码实现
类中,大量使用方法来调用递归方法的技巧,很好地体现了面向对象的封装性。
1 /**
2 * @author: wenhx
3 * @date: Created in 2019/10/8 19:41 (之前)
4 * @description: 二叉查找树的实现
5 */
6 public class BinarySearchTree<AnyType extends Comparable<? super AnyType>> {
7
8 /**
9 * 树的根节点
10 */
11 private BinaryNode<AnyType> root;
12
13 /**
14 * 定义树的节点(内部类)
15 */
16 private static class BinaryNode<AnyType> {
17
18 AnyType element; // 元素值
19 BinaryNode<AnyType> left; // 左孩子
20 BinaryNode<AnyType> right; // 右孩子
21
22 // 节点的构造器:初始化一个树的节点
23 BinaryNode(AnyType theElement) {
24 this(theElement, null, null);
25 }
26
27 BinaryNode(AnyType theElement, BinaryNode<AnyType> lt, BinaryNode<AnyType> rt) {
28 element = theElement;
29 left = lt;
30 right = rt;
31 }
32 }
33
34 /**
35 * 二叉排序树的构造器:初始化根节点
36 */
37 public BinarySearchTree() {
38 root = null;
39 }
40
41 /**
42 * 置空
43 */
44 public void makeEmpty() {
45 root = null;
46 }
47
48 /**
49 * 判空
50 */
51 public boolean isEmpty() {
52 return root == null;
53 }
54
55 /**
56 * 寻找最小值
57 */
58 public AnyType findMin() {
59 if (isEmpty()) {
60 throw new RuntimeException();
61 }
62 return findMin(root).element;
63 }
64
65 /**
66 * 寻找最大值
67 */
68 public AnyType findMax() {
69 if (isEmpty()) {
70 throw new RuntimeException();
71 }
72 return findMax(root).element;
73 }
74
75
76 /**
77 * 是否存在元素x
78 */
79 public boolean contains(AnyType x) {
80 return contains(x, root);
81 }
82
83 /**
84 * 插入元素x
85 */
86 public void insert(AnyType x) {
87 root = insert(x, root);
88 }
89
90 /**
91 * 删除元素x
92 */
93 public void remove(AnyType x) {
94 root = remove(x, root);
95 }
96
97 /**
98 * 遍历此二叉树
99 */
100 public void printTree() {
101 if (isEmpty()) {
102 System.out.println("Empty tree");
103 } else {
104 printTree(root);
105 }
106 }
107
108 /**
109 * 寻找最小值(内部方法):此处用递归实现
110 */
111 private BinaryNode<AnyType> findMin(BinaryNode<AnyType> t) {
112 if (t == null) {
113 return null;
114 } else if (t.left == null) {
115 return t;
116 }
117 return findMin(t.left);
118 }
119
120 /**
121 * 寻找最大值(内部方法):此处用非递归实现
122 */
123 private BinaryNode<AnyType> findMax(BinaryNode<AnyType> t) {
124 if (t != null) {
125 while (t.right != null) {
126 t = t.right;
127 }
128 }
129 return t;
130 }
131
132 /**
133 * 是否存在元素x(内部方法)
134 */
135 private boolean contains(AnyType x, BinaryNode<AnyType> t) {
136 /**
137 * 跳出递归的条件
138 */
139 if (t == null) {
140 return false;
141 }
142
143 /**
144 * 如果x小于节点值,则递归到左孩子;
145 * 如果x大于节点值,则递归到右孩子;
146 * 如果x等于节点值,则找到。
147 */
148 int compareResult = x.compareTo(t.element);
149
150 if (compareResult < 0) {
151 return contains(x, t.left);
152 } else if (compareResult > 0) {
153 return contains(x, t.right);
154 } else {
155 return true;
156 }
157
158 }
159
160 /**
161 * 插入元素x(内部方法)
162 */
163 private BinaryNode<AnyType> insert(AnyType x, BinaryNode<AnyType> t) {
164 /**
165 * 跳出递归的条件
166 */
167 if (t == null) {
168 return new BinaryNode<>(x, null, null);
169 }
170
171 /**
172 * 如果x小于节点值,则递归到左孩子;
173 * 如果x大于节点值,则递归到右孩子;
174 * 如果x等于节点值,则说明已有元素x,无需操作。
175 */
176 int compareResult = x.compareTo(t.element);
177
178 if (compareResult < 0) {
179 t.left = insert(x, t.left);
180 } else if (compareResult > 0) {
181 t.right = insert(x, t.right);
182 } else {
183 }
184 return t;
185
186 }
187
188 /**
189 * 删除元素x(内部方法)
190 */
191 private BinaryNode<AnyType> remove(AnyType x, BinaryNode<AnyType> t) {
192 /**
193 * 跳出递归的条件
194 */
195 if (t == null) {
196 return t; // Item not found; do nothing
197 }
198
199 /**
200 * 如果x小于节点值,则递归到左孩子;
201 * 如果x大于节点值,则递归到右孩子;
202 * 如果x等于节点值,则要删除此节点。
203 */
204 int compareResult = x.compareTo(t.element);
205
206 if (compareResult < 0) {
207 t.left = remove(x, t.left);
208 } else if (compareResult > 0) {
209 t.right = remove(x, t.right);
210 } else if (t.left != null && t.right != null) {
211 // 要删除的节点有两个孩子(可选用右孩子最小元素/左孩子最大元素上调)
212 t.element = findMin(t.right).element;
213 t.right = remove(t.element, t.right);
214 } else {
215 // 要删除的节点有一个孩子或者没有孩子
216 t = (t.left != null) ? t.left : t.right;
217 }
218 return t;
219 }
220
221 /**
222 * 遍历此二叉树(内部方法)
223 */
224 private void printTree(BinaryNode<AnyType> t) {
225 // 中序遍历-->即递增顺序
226 if (t != null) {
227 printTree(t.left);
228 System.out.println(t.element);
229 printTree(t.right);
230 }
231 }
232
233 /**
234 * 求树的深度(内部方法)
235 */
236 private int height(BinaryNode<AnyType> t) {
237 if (t == null) {
238 return -1;
239 } else {
240 return 1 + Math.max(height(t.left), height(t.right));
241 }
242 }
243
244 /**
245 * 主方法用来测试
246 */
247 public static void main(String[] args) {
248 BinarySearchTree<Integer> t = new BinarySearchTree<>();
249 t.insert(6);
250 t.insert(3);
251 t.insert(9);
252 t.insert(2);
253 t.insert(5);
254 t.insert(8);
255 t.insert(10);
256 t.printTree();
257 t.insert(4);
258 }
259 }