-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSearchTree.java
296 lines (253 loc) · 6.28 KB
/
SearchTree.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
package exercise4_8_searchtree;
import java.util.ArrayList;
/**
* Binary search tree implementation
*
*
*/
public class SearchTree {
private TreeNode root;
/** initializes an empty tree */
public SearchTree() {
root = null;
}
/** checks if tree is empty */
public boolean isEmpty() {
return (root == null);
}
/** computes height of the tree */
public int height() {
return height(root);
}
private int height(TreeNode r) {
if (r == null)
return 0;
else
return 1 + Math.max(height(r.left), height(r.right));
}
/**
* inserts a value into the tree
*/
public boolean insert(int v) {
if (root == null) {
// tree was empty
root = new TreeNode(v);
return true; // value successfully inserted
} else {
// insert v into the non-empty tree with the given root
return insertIter(root, v);
}
}
/**
* insert a value v into tree with root r, iterative version
*/
private boolean insertIter(TreeNode r, int v) {
while (true) {
if (v < r.info) {
if (r.left == null) {
r.left = new TreeNode(v);
return true;
} else {
r = r.left;
}
} else if (v > r.info) {
if (r.right == null) {
r.right = new TreeNode(v);
return true;
} else {
r = r.right;
}
} else
// if (v == r.info)
return false; // Wert war bereits vorhanden
}
}
/**
* search for value v in the tree
*
* @return node that contains value v, or null, if v is not contained in the
* tree
*/
public TreeNode searchNode(int v) {
return searchNodeRek(root, v);
}
public TreeNode searchNodeRek(TreeNode r, int v) {
if (r == null)
return null;
else {
if (v < r.info)
return searchNodeRek(r.left, v); // continue search in left subtree
else if (v > r.info)
return searchNodeRek(r.right, v); // continue search in right subtree
else
// v == r.value // value found
return r;
}
}
/**
* print the tree in 'graphical' form to the console
*/
public void print() {
if (root != null) {
print(root.left, " ", true);
System.out.println("+---" + root.info);
print(root.right, " ", false);
} else {
System.out.println("(empty tree)");
}
}
/** auxilliary method to print the tree in graphical form */
private void print(TreeNode r, String prefix, boolean links) {
if (r != null) {
if (links)
print(r.left, prefix + " ", links);
else
print(r.left, prefix + "| ", !links);
System.out.println(prefix + "+---" + r.info);
if (links)
print(r.right, prefix + "| ", !links);
else
print(r.right, prefix + " ", links);
}
}
/** Compute the sum of all values. */
public int sum() {
if(root == null)
return 0; //in case tree is empty
else
//compute sum recursively with another function
return recursiveSum(root);
}
public int recursiveSum(TreeNode r)
{
if(r == null)
return 0;
else
//recursively compute sum
return(r.info + recursiveSum (r.left) + recursiveSum (r.right));
}
/** computes the number of leaves */
public int numOfLeaves() {
if(root == null) //in case tree is empty
return 0;
else
//compute number of leaves recursively
return recursiveNumOfLeaves(root);
}
public int recursiveNumOfLeaves (TreeNode r)
{
if(r == null)
return 0;
//leaf exists
else if(r.left == null && r.right == null)
return 1;
else
//compute number of leaves recursively
return(recursiveNumOfLeaves (r.left) + recursiveNumOfLeaves (r.right));
}
/**
* removes the node with the minimal value
*
* @return value of the node that is removed
*/
public int extractMin() {
//empty tree case
if(root == null)
throw new RuntimeException("Can't extract min from empty tree!");
else
//search for minimum recursively
return recursiveExtractMin(root,null);
}
public int recursiveExtractMin (TreeNode r, TreeNode parent)
{
//minimum node reached
if(r.left == null)
{
int temp = r.info;
//if root is the minimum
if(r.info == root.info)
{
//if the root has no leaves
if(r.right == null)
root = null;
else
//if root has right(bigger) child, replace
root = root.right;
}
//if the leaf has no children, it can be deleted
else if(r.right == null)
parent.left = null;
else
//if min has right subtree, it will be attached to parent
parent.left = r.right;
return temp;
}
else
//continue searching
return recursiveExtractMin (r.left,r);
}
/**
* builds a sorted list of all values
*/
public ArrayList<Integer> toList()
{
ArrayList<Integer> arr = new ArrayList<Integer>();
//if list is empty
if(root == null)
return arr;
else
{
//use inorder traversal
traversal (root, arr);
return arr;
}
}
public void traversal (TreeNode r, ArrayList<Integer> arr)
{
if(r == null)
return;
//traverse left side
traversal (r.left,arr);
//add value to the array list
arr.add(r.info);
//traverse right side
traversal (r.right,arr);
}
/** checks if both trees contain the same set of values */
public boolean equals(SearchTree other) {
ArrayList<Integer> arrCurr = new ArrayList<Integer>(toList());
ArrayList<Integer> arrOther = new ArrayList<Integer>(other.toList());
//if length is different, they must be unequal
if(arrCurr.size() != arrOther.size())
return false;
else
{
//check if values are the same
for(int value : arrCurr)
if(!binaryContains(value,arrOther)) return false;
}
return true;
}
//binary search, iteratively implemented
public boolean binaryContains(int toFind, ArrayList<Integer> arr)
{
int low = 0;
int high = arr.size()-1;
int mid;
while(low <= high)
{
mid = low + (high - low) / 2;
//sought value smaller than current mid point -> search in smaller half
if(arr.get(mid) < toFind)
low = mid + 1;
//sought value larger than current mid point -> search larger half
else if(arr.get(mid) > toFind)
high = mid - 1;
//value = current midpoint -> successful search
else
return true;
}
//unsuccessful search
return false;
}
}