-
Notifications
You must be signed in to change notification settings - Fork 104
/
Copy pathBST.java
333 lines (298 loc) · 9.42 KB
/
BST.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
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
package ch_25.exercise25_02;
import ch_25.AbstractTree;
import java.util.*;
/**
* 25.2 (Test full binary tree) A full binary tree is a binary tree with the leaves on the
* same level. Add a method in the BST class to return true if the tree is a full
* binary tree. (Hint: The number of nodes in a full binary tree is 2depth - 1.)
* > Returns true if the tree is a 'full' binary tree
* <p>
* boolean isFullBST()
*/
public class BST<E extends Comparable<E>> extends AbstractTree<E> {
protected TreeNode<E> root;
protected int size = 0;
/* *************************************** Exercise25_02 (Start) ********************************************** */
public boolean isFullBST() {
return isFullBST(root);
}
public boolean isFullBST(TreeNode<E> root) {
if (root == null) {
return true;
} else if (root.left == null && root.right == null) {
return true;
} else if (root.left != null && root.right != null) {
return isFullBST(root.left) && isFullBST(root.right);
}
return false;
}
/* *************************************** Exercise25_02 (End) *********************************************** */
/**
* Create a default binary search tree
*/
public BST() {
}
/**
* Create a binary search tree from an array of objects
*/
public BST(E[] objects) {
for (int i = 0; i < objects.length; i++)
insert(objects[i]);
}
/**
* Return true if the element is in the tree
*/
@Override
public boolean search(E e) {
TreeNode<E> current = root; // Start from the root
while (current != null) {
if (e.compareTo(current.element) < 0) {
current = current.left;
} else if (e.compareTo(current.element) > 0) {
current = current.right;
} else // element matches current.element
return true; // Element is found
}
return false;
}
/**
* Insert element e into the binary search tree.
* Return true if the element is inserted successfully.
*/
@Override
public boolean insert(E e) {
if (root == null)
root = createNewNode(e); // Create a new root
else {
// Locate the parent node
TreeNode<E> parent = null;
TreeNode<E> current = root;
while (current != null)
if (e.compareTo(current.element) < 0) {
parent = current;
current = current.left;
} else if (e.compareTo(current.element) > 0) {
parent = current;
current = current.right;
} else
return false; // Duplicate node not inserted
// Create the new node and attach it to the parent node
if (e.compareTo(parent.element) < 0)
parent.left = createNewNode(e);
else
parent.right = createNewNode(e);
}
size++;
return true; // Element inserted successfully
}
protected TreeNode<E> createNewNode(E e) {
return new TreeNode<>(e);
}
@Override
/** Inorder traversal from the root */
public void inorder() {
inorder(root);
}
/**
* Inorder traversal from a subtree
*/
protected void inorder(TreeNode<E> root) {
if (root == null) return;
inorder(root.left);
System.out.print(root.element + " ");
inorder(root.right);
}
/**
* Postorder traversal from the root
*/
@Override
public void postorder() {
postorder(root);
}
/**
* Postorder traversal from a subtree
*/
protected void preorder(TreeNode<E> root) {
if (root == null) return;
postorder(root.left);
postorder(root.right);
System.out.print(root.element + " ");
}
/**
* Preorder traversal from the root
*/
@Override
public void preorder() {
preorder(root);
}
/**
* Preorder traversal from a subtree
*/
protected void postorder(TreeNode<E> root) {
if (root == null) return;
System.out.print(root.element + " ");
preorder(root.left);
preorder(root.right);
}
/**
* Remove all elements from the tree
*/
public void clear() {
root = null;
size = 0;
}
/**
* This inner class is static, because it does not access
* any instance members defined in its outer class
*/
public static class TreeNode<E extends Comparable<E>> {
protected E element;
protected TreeNode<E> left;
protected TreeNode<E> right;
public TreeNode(E e) {
element = e;
}
}
/**
* Get the number of nodes in the tree
*/
@Override
public int getSize() {
return size;
}
/**
* Returns the root of the tree
*/
public TreeNode<E> getRoot() {
return root;
}
/**
* Returns a path from the root leading to the specified element
*/
public ArrayList<TreeNode<E>> path(E e) {
ArrayList<TreeNode<E>> list =
new ArrayList<>();
TreeNode<E> current = root; // Start from the root
while (current != null) {
list.add(current); // Add the node to the list
if (e.compareTo(current.element) < 0) {
current = current.left;
} else if (e.compareTo(current.element) > 0) {
current = current.right;
} else
break;
}
return list; // Return an array list of nodes
}
/**
* Delete an element from the binary search tree.
* Return true if the element is deleted successfully.
* Return false if the element is not in the tree.
*/
@Override
public boolean delete(E e) {
// Locate the node to be deleted and also locate its parent node
TreeNode<E> parent = null;
TreeNode<E> current = root;
while (current != null) {
if (e.compareTo(current.element) < 0) {
parent = current;
current = current.left;
} else if (e.compareTo(current.element) > 0) {
parent = current;
current = current.right;
} else
break; // Element is in the tree pointed at by current
}
if (current == null)
return false; // Element is not in the tree
// Case 1: current has no left child
if (current.left == null) {
// Connect the parent with the right child of the current node
if (parent == null) {
root = current.right;
} else {
if (e.compareTo(parent.element) < 0)
parent.left = current.right;
else
parent.right = current.right;
}
} else {
// Case 2: The current node has a left child.
// Locate the rightmost node in the left subtree of
// the current node and also its parent.
TreeNode<E> parentOfRightMost = current;
TreeNode<E> rightMost = current.left;
while (rightMost.right != null) {
parentOfRightMost = rightMost;
rightMost = rightMost.right; // Keep going to the right
}
// Replace the element in current by the element in rightMost
current.element = rightMost.element;
// Eliminate rightmost node
if (parentOfRightMost.right == rightMost)
parentOfRightMost.right = rightMost.left;
else
// Special case: parentOfRightMost == current
parentOfRightMost.left = rightMost.left;
}
size--;
return true; // Element deleted successfully
}
/**
* Obtain an iterator. Use inorder.
*/
@Override
public Iterator<E> iterator() {
return new InorderIterator();
}
// Inner class InorderIterator
private class InorderIterator implements Iterator<E> {
// Store the elements in a list
private ArrayList<E> list = new ArrayList<>();
private int current = 0; // Point to the current element in list
public InorderIterator() {
inorder(); // Traverse binary tree and store elements in list
}
/**
* Inorder traversal from the root
*/
private void inorder() {
inorder(root);
}
/**
* Inorder traversal from a subtree
*/
private void inorder(TreeNode<E> root) {
if (root == null) return;
inorder(root.left);
list.add(root.element);
inorder(root.right);
}
/**
* More elements for traversing?
*/
@Override
public boolean hasNext() {
if (current < list.size())
return true;
return false;
}
/**
* Get the current element and move to the next
*/
@Override
public E next() {
return list.get(current++);
}
/**
* Remove the current element
*/
@Override
public void remove() {
delete(list.get(current)); // Delete the current element
list.clear(); // Clear the list
inorder(); // Rebuild the list
}
}
}