1 import java.util.ArrayList;
2
3 public class Tree24<E extends Comparable<E>> implements Tree<E> {
4 private Tree24Node<E> root;
5 private int size;
6
7
8 public Tree24() {
9 }
10
11
12 public Tree24(E[] elements) {
13 for (int i = 0; i < elements.length; i++)
14 insert(elements[i]);
15 }
16
17 @Override
18 public boolean search(E e) {
19 Tree24Node<E> current = root;
20
21 while (current != null) {
22 if (matched(e, current)) {
23 return true;
24 }
25 else {
26 current = getChildNode(e, current);
27 }
28 }
29
30 return false;
31 }
32
33
34 private boolean matched(E e, Tree24Node<E> node) {
35 for (int i = 0; i < node.elements.size(); i++)
36 if (node.elements.get(i).equals(e))
37 return true;
38
39 return false;
40 }
41
42
43 private Tree24Node<E> getChildNode(E e, Tree24Node<E> node) {
44 if (node.child.size() == 0)
45 return null;
46
47 int i = locate(e, node);
48 return node.child.get(i);
49 }
50
51 @Override
54 public boolean insert(E e) {
55 if (root == null)
56 root = new Tree24Node<E>(e);
57 else {
58
59 Tree24Node<E> leafNode = null;
60 Tree24Node<E> current = root;
61 while (current != null)
62 if (matched(e, current)) {
63 return false;
64 }
65 else {
66 leafNode = current;
67 current = getChildNode(e, current);
68 }
69
70
71 insert(e, null, leafNode);
72 }
73
74 size++;
75 return true;
76 }
77
78
79 private void insert(E e, Tree24Node<E> rightChildOfe,
80 Tree24Node<E> u) {
81
82 ArrayList<Tree24Node<E>> path = path(e);
83
84 for (int i = path.size() - 1; i >= 0; i--) {
85 if (u.elements.size() < 3) {
86 insert23(e, rightChildOfe, u);
87 break;
88 }
89 else {
90 Tree24Node<E> v = new Tree24Node<E>();
91 E median = split(e, rightChildOfe, u, v);
92
93 if (u == root) {
94 root = new Tree24Node<E>(median);
95 root.child.add(u);
96 root.child.add(v);
97 break;
98 }
99 else {
100
101 e = median;
102 rightChildOfe = v;
103 u = path.get(i - 1);
104 }
105 }
106 }
107 }
108
109
110 private void insert23(E e, Tree24Node<E> rightChildOfe,
111 Tree24Node<E> node) {
112 int i = this.locate(e, node);
113 node.elements.add(i, e);
114 if (rightChildOfe != null)
115 node.child.add(i + 1, rightChildOfe);
116 }
117
118
119 private E split(E e, Tree24Node<E> rightChildOfe,
120 Tree24Node<E> u, Tree24Node<E> v) {
121
122 v.elements.add(u.elements.remove(2));
123 E median = u.elements.remove(1);
124
125
126
127 if (u.child.size() > 0) {
128 v.child.add(u.child.remove(2));
129 v.child.add(u.child.remove(2));
130 }
131
132
133 if (e.compareTo(median) < 0)
134 insert23(e, rightChildOfe, u);
135 else
136 insert23(e, rightChildOfe, v);
137
138 return median;
139 }
140
141
142 private ArrayList<Tree24Node<E>> path(E e) {
143 ArrayList<Tree24Node<E>> list = new ArrayList<Tree24Node<E>>();
144 Tree24Node<E> current = root;
145
146 while (current != null) {
147 list.add(current);
148 if (matched(e, current)) {
149 break;
150 }
151 else {
152 current = getChildNode(e, current);
153 }
154 }
155
156 return list;
157 }
158
159 @Override
160 public boolean delete(E e) {
161
162 Tree24Node<E> node = root;
163 while (node != null)
164 if (matched(e, node)) {
165 delete(e, node);
166 size--;
167 return true;
168 }
169 else {
170 node = getChildNode(e, node);
171 }
172
173 return false;
174 }
175
176
177 private void delete(E e, Tree24Node<E> node) {
178 if (node.child.size() == 0) {
179
180 ArrayList<Tree24Node<E>> path = path(e);
181
182 node.elements.remove(e);
183
184 if (node == root) {
185 if (node.elements.size() == 0)
186 root = null;
187 return;
188 }
189
190 validate(e, node, path);
191 }
192 else {
193
194 int index = locate(e, node);
195 Tree24Node<E> current = node.child.get(index);
196 while (current.child.size() > 0) {
197 current = current.child.get(current.child.size() - 1);
198 }
199 E rightmostElement =
200 current.elements.get(current.elements.size() - 1);
201
202
203 ArrayList<Tree24Node<E>> path = path(rightmostElement);
204
205
206 node.elements.set(index, current.elements.remove(
207 current.elements.size() - 1));
208
209 validate(rightmostElement, current, path);
210 }
211 }
212
213
214 private void validate(E e, Tree24Node<E> u,
215 ArrayList<Tree24Node<E>> path) {
216 for (int i = path.size() - 1; u.elements.size() == 0; i--) {
217 Tree24Node<E> parentOfu = path.get(i - 1);
218 int k = locate(e, parentOfu);
219
220
221 if (k > 0 && parentOfu.child.get(k - 1).elements.size() > 1) {
222 leftSiblingTransfer(k, u, parentOfu);
223 }
224 else if (k + 1 < parentOfu.child.size() &&
225 parentOfu.child.get(k + 1).elements.size() > 1) {
226 rightSiblingTransfer(k, u, parentOfu);
227 }
228 else if (k - 1 >= 0) {
229
230 Tree24Node<E> leftNode = parentOfu.child.get(k - 1);
231
232
233 leftSiblingFusion(k, leftNode, u, parentOfu);
234
235
236 if (parentOfu == root && parentOfu.elements.size() == 0) {
237 root = leftNode;
238 break;
239 }
240
241 u = parentOfu;
242 }
243 else {
244
245 Tree24Node<E> rightNode = parentOfu.child.get(k + 1);
246
247
248 rightSiblingFusion(k, rightNode, u, parentOfu);
249
250
251 if (parentOfu == root && parentOfu.elements.size() == 0) {
252 root = rightNode;
253 break;
254 }
255
256 u = parentOfu;
257 }
258 }
259 }
260
261
262 private int locate(E o, Tree24Node<E> node) {
263 for (int i = 0; i < node.elements.size(); i++) {
264 if (o.compareTo(node.elements.get(i)) <= 0) {
265 return i;
266 }
267 }
268
269 return node.elements.size();
270 }
271
272
273 private void leftSiblingTransfer(int k,
274 Tree24Node<E> u, Tree24Node<E> parentOfu) {
275
276 u.elements.add(0, parentOfu.elements.get(k - 1));
277
278
279 Tree24Node<E> leftNode = parentOfu.child.get(k - 1);
280 parentOfu.elements.set(k - 1,
281 leftNode.elements.remove(leftNode.elements.size() - 1));
282
283
284 if (leftNode.child.size() > 0)
285 u.child.add(0, leftNode.child.remove(
286 leftNode.child.size() - 1));
287 }
288
289
290 private void rightSiblingTransfer(int k,
291 Tree24Node<E> u, Tree24Node<E> parentOfu) {
292
293 u.elements.add(parentOfu.elements.get(k));
294
295
296 Tree24Node<E> rightNode = parentOfu.child.get(k + 1);
297 parentOfu.elements.set(k, rightNode.elements.remove(0));
298
299
300 if (rightNode.child.size() > 0)
301 u.child.add(rightNode.child.remove(0));
302 }
303
304
305 private void leftSiblingFusion(int k, Tree24Node<E> leftNode,
306 Tree24Node<E> u, Tree24Node<E> parentOfu) {
307
308 leftNode.elements.add(parentOfu.elements.remove(k - 1));
309
310
311 parentOfu.child.remove(k);
312
313
314 if (u.child.size() > 0)
315 leftNode.child.add(u.child.remove(0));
316 }
317
318
319 private void rightSiblingFusion(int k, Tree24Node<E> rightNode,
320 Tree24Node<E> u, Tree24Node<E> parentOfu) {
321
322 rightNode.elements.add(0, parentOfu.elements.remove(k));
323
324
325 parentOfu.child.remove(k);
326
327
328 if (u.child.size() > 0)
329 rightNode.child.add(0, u.child.remove(0));
330 }
331
332 @Override
333 public int getSize() {
334 return size;
335 }
336
337 @Override
338 public void preorder() {
339 preorder(root);
340 }
341
342
343 private void preorder(Tree24Node<E> root) {
344 if (root == null)return;
345 for (int i = 0; i < root.elements.size(); i++)
346 System.out.print(root.elements.get(i) + " ");
347
348 for (int i = 0; i < root.child.size(); i++)
349 preorder(root.child.get(i));
350 }
351
352 @Override
353 public void inorder() {
354
355 }
356
357
358 public void postorder() {
359
360 }
361
362 @Override
363 public boolean isEmpty() {
364 return root == null;
365 }
366
367 @Override
368 public void clear() {
369 root = null;
370 size = 0;
371 }
372
373 @Override
374 public java.util.Iterator<E> iterator() {
375
376 return null;
377 }
378
379
380 protected static class Tree24Node<E extends Comparable<E>> {
381
382 ArrayList<E> elements = new ArrayList<E>(3);
383
384 ArrayList<Tree24Node<E>> child
385 = new ArrayList<Tree24Node<E>>(4);
386
387
388 Tree24Node() {
389 }
390
391
392 Tree24Node(E o) {
393 elements.add(o);
394 }
395 }
396 }