3
3
import java .util .LinkedList ;
4
4
import java .util .Queue ;
5
5
6
+ /*
7
+ * This entire class is used to build a Binary Tree data structure. There is the
8
+ * Node Class and the Tree Class, both explained below.
9
+ */
6
10
/**
7
- * A binary tree data structure where elements have two successors (children).
8
- * The left child is smaller than the parent, and the right child is larger.
11
+ * A binary tree is a data structure in which an element has two
12
+ * successors(children). The left child is usually smaller than the parent, and
13
+ * the right child is usually bigger.
9
14
*
10
15
* @author Unknown
11
16
*/
12
17
public class BinaryTree {
13
18
14
19
/**
15
- * Node class represents elements in the Binary Tree, with pointers to
16
- * the left and right children and a reference to its parent node.
20
+ * This class implements the nodes that will go on the Binary Tree. They
21
+ * consist of the data in them, the node to the left, the node to the right,
22
+ * and the parent from which they came from.
23
+ *
24
+ * @author Unknown
17
25
*/
18
26
static class Node {
27
+
28
+ /**
29
+ * Data for the node
30
+ */
19
31
public int data ;
20
- public Node left , right , parent ;
32
+ /**
33
+ * The Node to the left of this one
34
+ */
35
+ public Node left ;
36
+ /**
37
+ * The Node to the right of this one
38
+ */
39
+ public Node right ;
40
+ /**
41
+ * The parent of this node
42
+ */
43
+ public Node parent ;
21
44
22
- public Node (int value ) {
45
+ /**
46
+ * Constructor of Node
47
+ *
48
+ * @param value Value to put in the node
49
+ */
50
+ Node (int value ) {
23
51
data = value ;
24
- left = right = parent = null ;
52
+ left = null ;
53
+ right = null ;
54
+ parent = null ;
25
55
}
26
56
}
27
57
58
+ /**
59
+ * The root of the Binary Tree
60
+ */
28
61
private Node root ;
29
62
63
+ /**
64
+ * Constructor
65
+ */
30
66
public BinaryTree () {
31
67
root = null ;
32
68
}
33
69
70
+ /**
71
+ * Parameterized Constructor
72
+ */
34
73
public BinaryTree (Node root ) {
35
74
this .root = root ;
36
75
}
37
76
77
+ /**
78
+ * Method to find a Node with a certain value
79
+ *
80
+ * @param key Value being looked for
81
+ * @return The node if it finds it, otherwise returns the parent
82
+ */
38
83
public Node find (int key ) {
39
84
Node current = root ;
40
85
while (current != null ) {
41
86
if (key < current .data ) {
42
- if (current .left == null ) return current ;
87
+ if (current .left == null ) {
88
+ return current ; // The key isn't exist, returns the parent
89
+ }
43
90
current = current .left ;
44
91
} else if (key > current .data ) {
45
- if (current .right == null ) return current ;
92
+ if (current .right == null ) {
93
+ return current ;
94
+ }
46
95
current = current .right ;
47
- } else {
96
+ } else { // If you find the value return it
48
97
return current ;
49
98
}
50
99
}
51
100
return null ;
52
101
}
53
102
103
+ /**
104
+ * Inserts certain value into the Binary Tree
105
+ *
106
+ * @param value Value to be inserted
107
+ */
54
108
public void put (int value ) {
55
109
Node newNode = new Node (value );
56
110
if (root == null ) {
57
111
root = newNode ;
58
112
} else {
113
+ // This will return the soon to be parent of the value you're inserting
59
114
Node parent = find (value );
115
+
116
+ // This if/else assigns the new node to be either the left or right child of the parent
60
117
if (value < parent .data ) {
61
118
parent .left = newNode ;
62
119
parent .left .parent = parent ;
@@ -67,68 +124,141 @@ public void put(int value) {
67
124
}
68
125
}
69
126
127
+ /**
128
+ * Deletes a given value from the Binary Tree
129
+ *
130
+ * @param value Value to be deleted
131
+ * @return If the value was deleted
132
+ */
70
133
public boolean remove (int value ) {
134
+ // temp is the node to be deleted
71
135
Node temp = find (value );
72
- if (temp == null || temp .data != value ) return false ;
73
136
74
- if (temp .left == null && temp .right == null ) {
75
- if (temp == root )
137
+ // If the value doesn't exist
138
+ if (temp .data != value ) {
139
+ return false ;
140
+ }
141
+
142
+ // No children
143
+ if (temp .right == null && temp .left == null ) {
144
+ if (temp == root ) {
76
145
root = null ;
77
- else if (temp .parent .data < temp .data )
146
+ } // This if/else assigns the new node to be either the left or right child of the
147
+ // parent
148
+ else if (temp .parent .data < temp .data ) {
78
149
temp .parent .right = null ;
79
- else
150
+ } else {
80
151
temp .parent .left = null ;
152
+ }
81
153
return true ;
82
- } else if (temp .left != null && temp .right != null ) {
154
+ } // Two children
155
+ else if (temp .left != null && temp .right != null ) {
83
156
Node successor = findSuccessor (temp );
157
+
158
+ // The left tree of temp is made the left tree of the successor
84
159
successor .left = temp .left ;
85
160
successor .left .parent = successor ;
161
+
162
+ // If the successor has a right child, the child's grandparent is it's new parent
86
163
if (successor .parent != temp ) {
87
164
if (successor .right != null ) {
88
165
successor .right .parent = successor .parent ;
89
166
successor .parent .left = successor .right ;
90
- } else
167
+ } else {
91
168
successor .parent .left = null ;
169
+ }
92
170
successor .right = temp .right ;
93
171
successor .right .parent = successor ;
94
172
}
173
+
95
174
if (temp == root ) {
96
- root = successor ;
97
175
successor .parent = null ;
98
- } else {
176
+ root = successor ;
177
+ } // If you're not deleting the root
178
+ else {
99
179
successor .parent = temp .parent ;
100
- if (temp .parent .data < temp .data )
180
+
181
+ // This if/else assigns the new node to be either the left or right child of the
182
+ // parent
183
+ if (temp .parent .data < temp .data ) {
101
184
temp .parent .right = successor ;
102
- else
185
+ } else {
103
186
temp .parent .left = successor ;
187
+ }
104
188
}
105
189
return true ;
106
- } else {
107
- Node child = (temp .right != null ) ? temp .right : temp .left ;
108
- if (temp == root )
109
- root = child ;
190
+ } // One child
191
+ else {
192
+ // If it has a right child
193
+ if (temp .right != null ) {
194
+ if (temp == root ) {
195
+ root = temp .right ;
196
+ return true ;
197
+ }
198
+
199
+ temp .right .parent = temp .parent ;
200
+
201
+ // Assigns temp to left or right child
202
+ if (temp .data < temp .parent .data ) {
203
+ temp .parent .left = temp .right ;
204
+ } else {
205
+ temp .parent .right = temp .right ;
206
+ }
207
+ } // If it has a left child
110
208
else {
111
- child .parent = temp .parent ;
112
- if (temp .data < temp .parent .data )
113
- temp .parent .left = child ;
114
- else
115
- temp .parent .right = child ;
209
+ if (temp == root ) {
210
+ root = temp .left ;
211
+ return true ;
212
+ }
213
+
214
+ temp .left .parent = temp .parent ;
215
+
216
+ // Assigns temp to left or right side
217
+ if (temp .data < temp .parent .data ) {
218
+ temp .parent .left = temp .left ;
219
+ } else {
220
+ temp .parent .right = temp .left ;
221
+ }
116
222
}
117
223
return true ;
118
224
}
119
225
}
120
226
227
+ /**
228
+ * This method finds the Successor to the Node given. Move right once and go
229
+ * left down the tree as far as you can
230
+ *
231
+ * @param n Node that you want to find the Successor of
232
+ * @return The Successor of the node
233
+ */
121
234
public Node findSuccessor (Node n ) {
122
- if (n .right == null ) return n ;
235
+ if (n .right == null ) {
236
+ return n ;
237
+ }
123
238
Node current = n .right ;
124
- while (current .left != null ) current = current .left ;
125
- return current ;
239
+ Node parent = n .right ;
240
+ while (current != null ) {
241
+ parent = current ;
242
+ current = current .left ;
243
+ }
244
+ return parent ;
126
245
}
127
246
247
+ /**
248
+ * Returns the root of the Binary Tree
249
+ *
250
+ * @return the root of the Binary Tree
251
+ */
128
252
public Node getRoot () {
129
253
return root ;
130
254
}
131
255
256
+ /**
257
+ * Prints leftChild - root - rightChild This is the equivalent of a depth
258
+ * first search
259
+ *
260
+ * @param localRoot The local root of the binary tree
261
+ */
132
262
public void inOrder (Node localRoot ) {
133
263
if (localRoot != null ) {
134
264
inOrder (localRoot .left );
@@ -137,6 +267,11 @@ public void inOrder(Node localRoot) {
137
267
}
138
268
}
139
269
270
+ /**
271
+ * Prints root - leftChild - rightChild
272
+ *
273
+ * @param localRoot The local root of the binary tree
274
+ */
140
275
public void preOrder (Node localRoot ) {
141
276
if (localRoot != null ) {
142
277
System .out .print (localRoot .data + " " );
@@ -145,6 +280,11 @@ public void preOrder(Node localRoot) {
145
280
}
146
281
}
147
282
283
+ /**
284
+ * Prints leftChild - rightChild - root
285
+ *
286
+ * @param localRoot The local root of the binary tree
287
+ */
148
288
public void postOrder (Node localRoot ) {
149
289
if (localRoot != null ) {
150
290
postOrder (localRoot .left );
@@ -153,15 +293,38 @@ public void postOrder(Node localRoot) {
153
293
}
154
294
}
155
295
296
+ /**
297
+ * Prints the tree in a breadth first search order This is similar to
298
+ * pre-order traversal, but instead of being implemented with a stack (or
299
+ * recursion), it is implemented with a queue
300
+ *
301
+ * @param localRoot The local root of the binary tree
302
+ */
156
303
public void bfs (Node localRoot ) {
157
- if ( localRoot == null ) return ;
304
+ // Create a queue for the order of the nodes
158
305
Queue <Node > queue = new LinkedList <>();
159
- queue .add (localRoot );
306
+
307
+ // If the give root is null, then we don't add to the queue
308
+ // and won't do anything
309
+ if (localRoot != null ) {
310
+ queue .add (localRoot );
311
+ }
312
+
313
+ // Continue until the queue is empty
160
314
while (!queue .isEmpty ()) {
161
- Node node = queue .remove ();
162
- System .out .print (node .data + " " );
163
- if (node .left != null ) queue .add (node .left );
164
- if (node .right != null ) queue .add (node .right );
315
+ // Get the next node on the queue to visit
316
+ localRoot = queue .remove ();
317
+
318
+ // Print the data from the node we are visiting
319
+ System .out .print (localRoot .data + " " );
320
+
321
+ // Add the children to the queue if not null
322
+ if (localRoot .right != null ) {
323
+ queue .add (localRoot .right );
324
+ }
325
+ if (localRoot .left != null ) {
326
+ queue .add (localRoot .left );
327
+ }
165
328
}
166
329
}
167
- }
330
+ }
0 commit comments