-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathBinaryTree.java
326 lines (271 loc) · 11.6 KB
/
BinaryTree.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
/*
* *** Jai Fischer / COMP 272 001 ***
*
* Homework # 2 (Programming Assignment). This Java class defines a few basic
* manipulation operations of a binary trees.
*
* ONLY MODIFY THIS FILE (NOT 'Main.Java')
*
*/
import java.util.Queue;
import java.util.LinkedList;
/*
* Class BinaryTree
*
* This class defines a binary tree object; it is a tree structure where every
* node as at most two child nodes, which form the tree branches. That implies
* that each node within the tree has a degree of 0, 1, or 2. A node of degree
* zero (0) is called a terminal node, or leaf node.
*
* Each non-leaf node is often called a branch node, which will have either one or
* two children (a left and right child node). There is no order guarantee within
* this basic binary tree object. Given that this binary object is NOT a Binary Search Tree (BST), there is
* no guarantee on order in the tree.
*
* As just stated, the insert method does NOT guarantee the order within the tree, but
* its logic attempts to follow the rules of BSTs -- meaning the insert method will traverse
* the binary tree searching for a location to insert the new Node using traversal
* logic similar to BSTs. But again, this is not a BST, so there is no guarantee that
* the tree's order maintains that defined by a BST.
*
* Public methods:
* void deleteTree() - deletes the tree.
* Node insert(int data) - inserts a new node into the tree containing value 'data'.
* String preOrder() - return the tree in 'preorder' traversal in a String object.
*
* The following methods you will complete:
* void replaceValue(int k, int l) - if data value 'k' is in tree, replace with data
* value 'l'; for simplicity at the moment, do not re-organize
* the tree based on new value which means this operation may
* violate the binary tree definition.
* int findMin() - returns the small data value stored in the tree.
* int nodesGT(int val) - return the number of nodes in the tree that have a data value
* greater than 'val'.
* double average() - return the average data value of all data values stored in
* the tree.
*/
public class BinaryTree {
// Constructors
public BinaryTree() {
root = null;
}
public BinaryTree(Node node) {
root = node;
}
/*
* Class Node
*
* The node object definition for each node of the bin ary tree.
*/
static class Node {
Node(int d) {
data = d;
left = null;
right = null;
}
Node(int d, Node l, Node r) {
data = d;
left = l;
right = r;
}
public int data;
public Node left;
public Node right;
} /* End Class Node */
public Node root;
public void deleteTree() {
root = null;
}
public void replaceValue(int oldVal, int newVal) {
replaceValueHelper(root, oldVal, newVal);
}
public int findMin() {
return findMinHelper(root);
}
public int nodesGT(int val) {
return nodesGTHelper(root, val);
}
/*
* public method insert
*
* The method will insert a node into the binary tree containing the value
* passed in as a parameter, 'data'. This insert routine maintains the
* form of the binary tree which maintains teh property of a 'complete binary'
* tree.
*
* The property basically implies that for every node in the tree:
* 1) every node in the tree has 2 children, except for possibly the last level.
* 2) and on the last level, all nodes are as far left as possible.
*
* There are no order properties of a basic binary tree.
*
* This method uses a breath first search of the binary tree to locate the
* location of where to insert the new node. This approach basically starts at
* the root, and searches level by level until the next free spot for the insertion.
* This approach maintains the 'complete tree' property of the binary tree.
*/
Node insert(int data) {
Node tempNode = new Node(data);
// If tree is empty, insert new node as the root.
if (root == null)
return root = tempNode;
// Create a queue to do level order traversal
Queue<Node> queue = new LinkedList<>();
queue.add(root);
// Do level order traversal
while (!queue.isEmpty()) {
Node front = queue.peek();
if (front.left == null) {
front.left = tempNode;
break;
} else if (front.right == null) {
front.right = tempNode;
break;
} else {
// If front node in queue has both left and right
// children, remove it from the queue.
queue.remove();
}
// Enqueue the left and right children of teh current node
if (front.left != null)
queue.add(front.left);
if (front.right != null)
queue.add(front.right);
}
return tempNode;
} // End method insert
/*
* Public method preOrder()
*
* This method will generate a String object containing a copy of the tree's
* data values in preorder traversal format. If tree is empty, and empty
* String object (e.g., "") is returned. Else the String object contains
* the data values, separated by a space.
*
* This public method is simply wrapper for the preOrderHelper private method
* which does the actual work. The public wrapper method simply passes the root
* of the tree to helper method.
*/
public String preOrder() {
return preOrderHelper(root);
}
public String preOrderHelper(Node node) {
if (node == null) {
return "";
}
return node.data + " " + preOrderHelper(node.left)
+ preOrderHelper(node.right);
}
/***********************************************************
*
* YOUR CODE GOES BELOW
*
* THERE IS NO NEED TO CHANGE ANY CODE ABOVE. DO NOT FORGET TO PLACE
* YOUR NAME AND SECTION NUMBER AT THE TOP OF THE FILE.
*
* YOU ARE TO WRITE THE METHODS:
* - replaceValue
* - findMin
* - NodesGT
* - average
*
***********************************************************/
/*
* private method replaceValueHelper
*
* This method will traverse the tree using a depth first search
* approach, and for each node found with the value of 'oldVal',
* replace it (update teh value in place), with the provided 'newVal'.
*
* Depth first search of the tree is based on recursion. This will result
* in very few lines of code.
*
*/
private void replaceValueHelper(Node node, int oldVal, int newVal) {
// ADD YOUR CODE HERE -- USE DEPTH FIRST SEARCH OF
// BINARY TREE (WHICH IS BASED ON RECURSION)
if(node.left != null) replaceValueHelper(node.left, oldVal, newVal); // Checks if left node exists
if(node.data == oldVal) node.data = newVal; // If the old value is found it will change it to the new value
if(node.right != null) replaceValueHelper(node.right, oldVal, newVal); // Checks if right node exists
}
/*
* private method findMinHelper()
*
* This method will traverse the tree using depth first search traversal and
* return the minimum data value in the binary tree. If the tree is empty, the
* value 'Integer.MAX_VALUE' is returned. Recall that this is not a binary
* search Tree (BST), so it does not have the additional property that the
* smaller data values always traverse the left child. So that implies all
* node is this tree must be traversed.
*
* Depth first search of the tree is based on recursion. This will result
* in very few lines of code.
*/
private int findMinHelper(Node node) {
// ADD YOUR CODE HERE -- USE DEPTH FIRST SEARCH OF
// BINARY TREE (WHICH IS BASED ON RECURSION)
int min = Integer.MAX_VALUE; // Makes minimum value Integer.MAX_VALUE
if(node == null) return min; // Returns min if node current node doesn't exist
min = node.data; // Makes the minimum the current nodes data value
return Math.min(Math.min(min, findMinHelper(node.left)),Math.min(min, findMinHelper(node.right))); // Returns the minimum value between the left, right, and current node
}
/*
* private method nodeGTHelper()
*
* This method will traverse the tree using depth first search traversal and
* return a count on the number of nodes that contain a data value larger
* than the parameter 'val'.
*
* If the tree is empty, return 0.
*
* Depth first search of the tree is based on recursion. This will result
* in very few lines of code.
*/
private int nodesGTHelper(Node node, int val) {
// ADD YOUR CODE HERE -- USE DEPTH FIRST SEARCH OF
// BINARY TREE (WHICH IS BASED ON RECURSION)
// return -1; // RECALL, IF TREE IS EMPTY, RETURN -1
// I am not sure if this is a typo or not but the instructions above
// state that if the tree is empty to return 0, so that is what I did
int i = 0; // Variable i acts as the counter for how many nodes have a value greater than val
if(node == null) return i; // returns i if current node doesn't exist
if(node.data > val) i++; // Increments i when the current nodes value is greater than val
return i + nodesGTHelper(node.left,val) + nodesGTHelper(node.right,val); // Returns the i values of the left and right and current node
}
/*
* public method average()
*
* This method will traverse the tree using depth first search traversal and
* return the average value contained in the binary tree. To easily perform a depth
* first traversal, it invokes the helper method, averageHelper(), which is the
* method that should be called recursively. If the tree is empty, 0 should be
* returned.
*
* IMPORTANT NOTE:
* The helper method should return an array of two integer values. In index
* location [0] is the sum of all data values in the tree. And in index
* location [1] is the count of nodes.
*
* As can be seen in the method average() immediately below, the returned average
* value is calculated as "sum / count".
*
* Depth first search of the tree is based on recursion. This will result
* in very few lines of code within the helper method.
*/
public double average() {
int[] sumAndCount = averageHelper(root);
return (double) sumAndCount[0] / sumAndCount[1];
}
private int[] averageHelper(Node n) {
// ADD YOUR CODE HERE -- USE DEPTH FIRST SEARCH OF
// BINARY TREE (WHICH IS BASED ON RECURSION)
// RECALL, IF THE TREE IS EMPTY, RETURN 0 FOR BOTH THE SUM AND
// COUNT LOCATIONS IN THE RETURNED ARRAY AS SHOWN BELOW, ELSE
// THE 'SUM' IS RETURNED IN INDEX LOCATION 0, AND COUNT IS LOCATION 1
int[] a = new int[]{0,0}; // Array a[] keeps track of sum and count
if (n == null) return a; // Returns a[] if the current node doesn't exist
a[0] += n.data + averageHelper(n.left)[0] + averageHelper(n.right)[0]; // Adds the sums of the left, right and current nodes data values
a[1] += 1 + averageHelper(n.left)[1] + averageHelper(n.right)[1]; // Adds the count of nodes together
return a; // Returns the array with the sum of node data values and count of nodes
}
}