Skip to content

Commit d987c69

Browse files
committed
add BST
1 parent 3bd0443 commit d987c69

File tree

2 files changed

+311
-0
lines changed

2 files changed

+311
-0
lines changed

BST/src/BST.java

Lines changed: 290 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,290 @@
1+
import java.util.LinkedList;
2+
import java.util.Queue;
3+
import java.util.Stack;
4+
5+
public class BST<E extends Comparable<E>> {
6+
private class Node {
7+
public E e;
8+
public Node left, right;
9+
10+
public Node(E e) {
11+
this.e = e;
12+
left = null;
13+
right = null;
14+
}
15+
}
16+
17+
private Node root;
18+
private int size;
19+
20+
public BST() {
21+
root = null;
22+
size = 0;
23+
}
24+
25+
public int size() {
26+
return size;
27+
}
28+
29+
public boolean isEmpty() {
30+
return size == 0;
31+
}
32+
33+
// 向二分搜索树中添加新的元素e
34+
public void add(E e) {
35+
root = add(root, e);
36+
}
37+
38+
// 向以node为根的二分搜索树中插入元素e,递归算法
39+
private Node add(Node node, E e) {
40+
if (node == null) {
41+
size++;
42+
return new Node(e);
43+
}
44+
45+
if (e.compareTo(node.e) > 0)
46+
node.left = add(node.left, e);
47+
else if (e.compareTo(node.e) < 0)
48+
node.right = add(node.right, e);
49+
50+
return node;
51+
}
52+
53+
// 查看二分搜索树种是否包含元素e
54+
private boolean contains(E e) {
55+
return contains(root, e);
56+
}
57+
58+
// 以node 为根的二分搜索树中是否包含元素e,递归算法
59+
private boolean contains(Node node, E e) {
60+
if (node == null)
61+
return false;
62+
63+
if (e.compareTo(node.e) == 0)
64+
return true;
65+
else if (e.compareTo(node.e) < 0)
66+
return contains(node.left, e);
67+
else// e.compareTo(node.e) > 0
68+
return contains(node.right, e);
69+
}
70+
71+
// 二分搜索树的递归前序遍历
72+
public void preOrder() {
73+
preOrder(root);
74+
}
75+
76+
private void preOrder(Node node) {
77+
if (node == null)
78+
return;
79+
80+
System.out.println(node.e);
81+
preOrder(node.left);
82+
preOrder(node.right);
83+
}
84+
85+
86+
// 二分搜索树的中序遍历
87+
public void inOrder() {
88+
inOrder(root);
89+
}
90+
91+
private void inOrder(Node node) {
92+
if (node == null)
93+
return;
94+
95+
preOrder(node.left);
96+
System.out.println(node.e);
97+
preOrder(node.right);
98+
}
99+
100+
// 二分搜索树的后序遍历
101+
public void postOrder() {
102+
postOrder(root);
103+
}
104+
105+
private void postOrder(Node node) {
106+
if (node == null)
107+
return;
108+
109+
preOrder(node.left);
110+
preOrder(node.right);
111+
System.out.println(node.e);
112+
}
113+
114+
115+
// 二分搜索树的非递归前序遍历
116+
public void preOrderNR() {
117+
Stack<Node> stack = new Stack<>();
118+
stack.push(root);
119+
while (!stack.isEmpty()) {
120+
Node cur = stack.pop();
121+
System.out.println(cur.e);
122+
123+
if (cur.right != null) {
124+
stack.push(cur.right);
125+
126+
}
127+
if (cur.left != null) {
128+
stack.push(cur.left);
129+
130+
}
131+
}
132+
}
133+
134+
// 二分搜索树的层序遍历
135+
public void levelOrder() {
136+
Queue<Node> q = new LinkedList<>();
137+
((LinkedList<Node>) q).add(root);
138+
while (!q.isEmpty()) {
139+
Node cur = q.remove();
140+
System.out.println(cur.e);
141+
142+
if (cur.right != null) {
143+
((LinkedList<Node>) q).add(cur.right);
144+
145+
}
146+
if (cur.left != null) {
147+
((LinkedList<Node>) q).add(cur.left);
148+
149+
}
150+
}
151+
}
152+
153+
// 寻找二分搜索树的最小元素
154+
public E minmum() {
155+
if (size == 0)
156+
throw new IllegalArgumentException("BST is empty!");
157+
158+
return minmum(root).e;
159+
}
160+
161+
private Node minmum(Node node) {
162+
if (node.left == null)
163+
return node;
164+
return minmum(node);
165+
}
166+
167+
// 寻找二分搜索树的最大元素
168+
public E maxmum() {
169+
if (size == 0)
170+
throw new IllegalArgumentException("BST is empty!");
171+
172+
return maxmum(root).e;
173+
}
174+
175+
private Node maxmum(Node node) {
176+
if (node.right == null)
177+
return node;
178+
return maxmum(node);
179+
}
180+
181+
// 删除二分搜索树的最小元素所在节点,返回最小值
182+
public E removeMin() {
183+
E ret = minmum();
184+
root = removeMin(root);
185+
return ret;
186+
}
187+
188+
// 删除以node为根的二分搜索树中的最小节点
189+
// 返回删除节点后新的二分搜索树的根
190+
private Node removeMin(Node node) {
191+
if (node.left == null) {
192+
Node rightNode = node.right;
193+
node.right = null;
194+
size--;
195+
return rightNode;
196+
}
197+
198+
node.left = removeMin(node.left);
199+
return node;
200+
}
201+
202+
public E removeMax() {
203+
E ret = maxmum();
204+
root = removeMax(root);
205+
return ret;
206+
}
207+
208+
public Node removeMax(Node node) {
209+
if (node.right == null) {
210+
Node nodeLeft = node.left;
211+
node.left = null;
212+
return nodeLeft;
213+
}
214+
215+
node.right = removeMax(node.right);
216+
return node;
217+
}
218+
219+
// 从二分搜索树中删除元素为e的节点
220+
public void remove(E e) {
221+
root = remove(root, e);
222+
}
223+
224+
private Node remove(Node node, E e) {
225+
if (node == null)
226+
return null;
227+
228+
if (e.compareTo(node.e) < 0) {
229+
node.left = remove(node.left, e);
230+
return node;
231+
} else if (e.compareTo(node.e) > 0) {
232+
node.right = remove(node.right, e);
233+
return node;
234+
} else { // e.equals(node.e)
235+
236+
// 待删除节点左子树为空
237+
if (node.left == null) {
238+
Node rightNode = node.right;
239+
node.right = null;
240+
size--;
241+
return rightNode;
242+
}
243+
// 待删除节点右子树为空
244+
if (node.right == null) {
245+
Node leftNode = node.left;
246+
node.left = null;
247+
size--;
248+
return leftNode;
249+
}
250+
251+
// 待删除节点左右子树均不为空
252+
// 找到比待删除节点大的最小节点,即待删除节点右子树的最小节点
253+
// 用这个节点顶替待删除节点的位置
254+
Node successor = minmum(node.right);
255+
successor.right = removeMin(node.right);
256+
successor.left = node.left;
257+
258+
node.left = node.right = null;
259+
260+
return successor;
261+
}
262+
}
263+
264+
@Override
265+
public String toString() {
266+
StringBuilder res = new StringBuilder();
267+
generateBSTString(root, 0, res);
268+
return res.toString();
269+
}
270+
271+
private void generateBSTString(Node node, int depth, StringBuilder res) {
272+
if (node == null) {
273+
res.append(generateBSTString(depth) + "null\n");
274+
return;
275+
}
276+
277+
res.append(generateBSTString(depth) + node.e + "\n");
278+
generateBSTString(node.left, depth + 1, res);
279+
generateBSTString(node.right, depth + 1, res);
280+
}
281+
282+
private String generateBSTString(int depth) {
283+
StringBuilder res = new StringBuilder();
284+
for (int i = 0; i < depth; i++) {
285+
res.append("--");
286+
}
287+
return res.toString();
288+
289+
}
290+
}

BST/src/Main.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
public class Main {
2+
3+
4+
public static void main(String[] args) {
5+
BST<Integer> bst = new BST<>();
6+
int[] nums = {5, 3, 6, 8, 4, 2};
7+
for (int num : nums) {
8+
bst.add(num);
9+
}
10+
// bst.preOrder();
11+
// System.out.println();
12+
// bst.preOrderNR();
13+
// System.out.println();
14+
// bst.inOrder();
15+
// System.out.println();
16+
// bst.postOrder();
17+
// System.out.println();
18+
// System.out.println(bst);
19+
bst.levelOrder();
20+
}
21+
}

0 commit comments

Comments
 (0)