详解二叉搜索树

2020-05-09

鉴于不经常使用的东西会经常遗忘,于是,总结了一下,记下来,供后续翻阅。

要点:

    1. 先判断树是否为空,为空则先init树
    2. 从根节点遍历,如果大于根节点,找右边,否则找左边,递归,找到left或者right为null的
    3. 插入
    1. left != null 的找前继节点
    2. right == null 的找后继节点
    1. 先删
    2. 后加
    1. 从根节点遍历,如果大于根节点,找右边,否则找左边
    2. 找不到的抛异常
  • 前序遍历
    1. 根左右
  • 中序遍历
    1. 左根右
  • 后续遍历
    1. 左右根
  • 层次遍历
    1. 引入队列

说明

使用了lombok插件,安装方式:

1
2
3
4
5
6
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
<scope>provided</scope>
</dependency>

源码

BinaryTree.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import lombok.Data;

/**
* 定义树结构
*/
@Data
public class BinaryTree {
// 节点数据
public int data;

// 左节点
public BinaryTree left;

// 右节点
public BinaryTree right;

BinaryTree(int data){
this.data = data;
}
}

BinaryTreeImpl.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
import java.util.LinkedList;
import java.util.Queue;

/**
* 实现二叉搜索树的增删改查 4种遍历
*/
public class BinaryTreeImpl {

// 根节点
public static BinaryTree root = null;

public static Queue<BinaryTree> list = new LinkedList<BinaryTree>();


/**
* 初始化树
*/
public static void init(int data){
if(root == null){
root = new BinaryTree(data);
root.setLeft(null);
root.setRight(null);
}
}

/**
* 添加
* @param data
*/
public static void add(int data){
if(root == null){
init(data);
}else{
addNode(root, data);
}
}

/**
* @param old_data
* @param new_data
*/
public static void update(int old_data, int new_data) {
try {
delete(old_data);
add( new_data);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}


/**
* 删除
* @param data
*/
public static void delete(int data){
deleteNode(root, data);
}

/**
*
* @param binaryTree
* @param data
*/
public static void deleteNode(BinaryTree binaryTree, int data){
//
try {
BinaryTree targetTree = findNode(root, data);
if(targetTree.getLeft() != null){
findAfter(targetTree);
}
if(targetTree.getRight() == null){
findPre(root, data);
}
} catch (Exception e) {
System.out.println(e.getMessage());
}

}

/**
* 找前继节点
* @param binaryTree
*/
public static void findPre(BinaryTree binaryTree, int data){
if(binaryTree.getRight().getData() == data){
binaryTree.setRight(null);
}
if(binaryTree.getData() > data){
// left
findPre(binaryTree.getLeft(), data);
}
if(binaryTree.getData() < data){
// right
findPre(binaryTree.getRight(), data);
}
}

/**
* 找后继节点
* @param binaryTree
*/
public static void findAfter(BinaryTree binaryTree){
BinaryTree right = binaryTree.getRight();
binaryTree.setData(right.getData());
binaryTree.setRight(right.getRight());
}

/**
* 查找
* @param data
*/
public static void find(int data){
try {
System.out.println(findNode(root, 3).getData());
} catch (Exception e) {
System.out.println(e.getMessage());
}
}

/**
*
* @param binaryTree
* @param data
* @return
*/
public static BinaryTree findNode(BinaryTree binaryTree, int data) throws Exception{
// check root first
if(binaryTree.data == data){
return binaryTree;
}
if(binaryTree.data > data && binaryTree.getLeft() != null){
// left
return findNode(binaryTree.getLeft(), data);
}
if(binaryTree.data < data && binaryTree.getRight() != null){
// right
return findNode(binaryTree.getRight(), data);
}
// not found
throw new Exception("not found: " + data);
}


/**
*
* @param binaryTree
* @param data
* @return
*/
public static void addNode(BinaryTree binaryTree, int data){
// Don't consider equality
if(binaryTree.data > data){
if(binaryTree.getLeft() == null){
binaryTree.setLeft(new BinaryTree(data));
}else{
addNode(binaryTree.getLeft(), data);
}
}else if(binaryTree.data < data){ // put data on right
if(binaryTree.getRight() == null){
binaryTree.setRight(new BinaryTree(data));
}else{
addNode(binaryTree.getRight(),data);
}
}
}



/**
* 前序遍历
* @param binaryTree
*/
public static void preTraverse(BinaryTree binaryTree){
// rules : root left right
// print root data first
System.out.println(binaryTree.data);

if(binaryTree.getLeft() != null){
preTraverse(binaryTree.getLeft());
}

if(binaryTree.getRight() != null){
preTraverse(binaryTree.getRight());
}

}

/**
* 中序遍历
* @param binaryTree
*/
public static void midTraverse(BinaryTree binaryTree){
// rules : left root right

if(binaryTree.getLeft() != null){
midTraverse(binaryTree.getLeft());
}

System.out.println(binaryTree.data);

if(binaryTree.getRight() != null){
midTraverse(binaryTree.getRight());
}

}

/**
* 后序遍历
* @param binaryTree
*/
public static void afterTraverse(BinaryTree binaryTree){
// rules : left right root

if(binaryTree.getLeft() != null){
afterTraverse(binaryTree.getLeft());
}

if(binaryTree.getRight() != null){
afterTraverse(binaryTree.getRight());
}

System.out.println(binaryTree.data);

}

/**
* 层次遍历
*/
public static void gradationTraverse(){
enqueue(root);
gradationTraverse(list);
}

/**
*
* @param list
*/
public static void gradationTraverse(Queue<BinaryTree> list){
for(;;){
if(!list.isEmpty()){
BinaryTree tree = list.poll();
System.out.println(tree.getData());
if(tree.getLeft() != null){
enqueue(tree.getLeft());
}
if(tree.getRight() != null){
enqueue(tree.getRight());
}
}else {
break;
}
}
}

/**
*
* @param binaryTree
*/
public static void enqueue(BinaryTree binaryTree){
list.add(binaryTree);
}


public static void main(String[] args) {

// 7 3 5 2 6 8 9
add(7);
add(3);
add(5);
add(2);
add(6);
add(8);
add(9);

// preTraverse(root);
// update(3, 2);
// find(3);
// System.out.println("------");
// 这里如果没有自平衡,更新后的树可能不是一个二叉搜索树了
update(3, 99);
// preTraverse(root);
// gradationTraverse();
// delete(9);
preTraverse(root);


}

}
使用支付宝打赏
使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

扫描二维码,分享此文章