b tree的java实现
1package bTree;
2
3import java.io.Serializable;
4import java.util.Iterator;
5
6/**
7 * Interface for a b tree
8 *
9 * @author
10 * @version 1.0
11 */
12public interface IBTree extends Serializable
13{
14 /**
15 * Method that will add an node into the b tree
16 *
17 * @param o node to add
18 */
19 @SuppressWarnings("unchecked")
20 public void add(Comparable o);
21
22 /**
23 * Method that will remove an node from the b tree
24 *
25 * @param o node to remove
26 * @return object
27 */
28 @SuppressWarnings("unchecked")
29 public Object remove(Comparable o);
30
31 /**
32 * Method that will find the element belongs to the specified node
33 *
34 * @param o node to find
35 * @return object
36 */
37 @SuppressWarnings("unchecked")
38 public Object find(Comparable o);
39
40 /**
41 * Method that will return an iterator of the b tree
42 *
43 * @return the iterator of the b tree
44 */
45 @SuppressWarnings("unchecked")
46 public Iterator iterator();
47
48 /**
49 * Method that will clear the b tree
50 */
51 public void clear();
52
53 /**
54 * Method that will check to see if the b tree is null
55 *
56 * @return true if the b tree is null, false if it is not
57 */
58 public boolean isEmpty();
59}
60
2
3import java.io.Serializable;
4import java.util.Iterator;
5
6/**
7 * Interface for a b tree
8 *
9 * @author
10 * @version 1.0
11 */
12public interface IBTree extends Serializable
13{
14 /**
15 * Method that will add an node into the b tree
16 *
17 * @param o node to add
18 */
19 @SuppressWarnings("unchecked")
20 public void add(Comparable o);
21
22 /**
23 * Method that will remove an node from the b tree
24 *
25 * @param o node to remove
26 * @return object
27 */
28 @SuppressWarnings("unchecked")
29 public Object remove(Comparable o);
30
31 /**
32 * Method that will find the element belongs to the specified node
33 *
34 * @param o node to find
35 * @return object
36 */
37 @SuppressWarnings("unchecked")
38 public Object find(Comparable o);
39
40 /**
41 * Method that will return an iterator of the b tree
42 *
43 * @return the iterator of the b tree
44 */
45 @SuppressWarnings("unchecked")
46 public Iterator iterator();
47
48 /**
49 * Method that will clear the b tree
50 */
51 public void clear();
52
53 /**
54 * Method that will check to see if the b tree is null
55 *
56 * @return true if the b tree is null, false if it is not
57 */
58 public boolean isEmpty();
59}
60
1package bTree;
2
3import java.util.*;
4
5/**
6 * @author
7 * @version 1.0
8 */
9public class BTree implements IBTree
10{
11 /**
12 * Attributes
13 */
14 private static final long serialVersionUID = 1L;
15 private BTreeNode root;
16 private int order;
17
18 /**
19 * Constructor
20 */
21 public BTree(int order)
22 {
23 this.order = order;
24 this.root = null;
25 }
26
27 /**
28 * Constructor
29 */
30 public BTree()
31 {
32 this.order = 3;
33 this.root = null;
34 }
35 /**
36 * private class used as the tree node
37 *
38 * @author
39 * @version 1.0
40 */
41 private class BTreeNode
42 {
43 /**
44 * Attributes
45 */
46 private BTreeNode fatherNode;
47 private ArrayList<BTreeNode> childrenNodes;
48 @SuppressWarnings("unchecked")
49 private ArrayList<Comparable> elements;
50 private int order;
51 private int position;
52
53 @SuppressWarnings("unchecked")
54 public BTreeNode(int order, Comparable element)
55 {
56 this.order = order;
57 this.elements = new ArrayList<Comparable>();
58 elements.add(element);
59 this.childrenNodes = null;
60 this.fatherNode = null;
61 this.position = -1;
62 }
63
64 @SuppressWarnings("unchecked")
65 public BTreeNode(int order)
66 {
67 this.order = order;
68 this.elements = new ArrayList<Comparable>();
69 this.childrenNodes = null;
70 this.fatherNode = null;
71 this.position = -1;
72 }
73
74 /**
75 * Class attribute getter
76 *
77 * @return the position
78 */
79 public int getPosition()
80 {
81 return this.position;
82 }
83
84 /**
85 * Class attribute setter
86 *
87 * @param position the position to set
88 */
89 public void setPosition(int position)
90 {
91 this.position = position;
92 }
93
94 /**
95 * Class attribute getter
96 *
97 * @return the order
98 */
99 public int getOrder()
100 {
101 return this.order;
102 }
103
104 /**
105 * Class attribute setter
106 *
107 * @param order the order to set
108 */
109 public void setOrder(int order)
110 {
111 this.order = order;
112 }
113
114 /**
115 * Class attribute getter
116 *
117 * @return the count
118 */
119 public int getCount()
120 {
121 return this.elements.size();
122 }
123
124 /**
125 * Class attribute getter
126 *
127 * @return the fatherNode
128 */
129 public BTreeNode getFatherNode()
130 {
131 return this.fatherNode;
132 }
133
134 /**
135 * Class attribute setter
136 *
137 * @param fatherNode the fatherNode to set
138 */
139 public void setFatherNode(BTreeNode fatherNode)
140 {
141 this.fatherNode = fatherNode;
142 }
143
144 /**
145 * Class attribute getter
146 *
147 * @return the childrenNodes
148 */
149 public ArrayList<BTreeNode> getChildrenNodes()
150 {
151 return this.childrenNodes;
152 }
153
154 /**
155 * Class attribute setter
156 *
157 * @param childrenNodes the childrenNodes to set
158 */
159 public void setChildrenNodes(ArrayList<BTreeNode> childrenNodes)
160 {
161 this.childrenNodes = childrenNodes;
162 }
163
164 /**
165 * Class attribute getter
166 *
167 * @return the elements
168 */
169 @SuppressWarnings("unchecked")
170 public ArrayList<Comparable> getElements()
171 {
172 return this.elements;
173 }
174
175 /**
176 * Class attribute setter
177 *
178 * @param elements the elements to set
179 */
180 @SuppressWarnings("unchecked")
181 public void setElements(ArrayList<Comparable> elements)
182 {
183 this.elements = elements;
184 }
185 }
186
187 /*
188 * (non-Javadoc)
189 *
190 * @see bTree.IBTree#add(java.lang.Comparable)
191 */
192 @SuppressWarnings("unchecked")
193 @Override
194 public void add(Comparable o)
195 {
196 Object object = find(o);
197 if(object != null)
198 {
199 return;
200 }
201 if(this.root == null)// first element
202 {
203 BTreeNode btn = new BTreeNode(this.order, o);
204 this.root = btn;
205 }
206 else
207 // more than one element
208 {
209 addToLeaf(this.root, o);
210 }
211 }
212
213 @SuppressWarnings("unchecked")
214 private void split(BTreeNode btn)// when sub nodes and elements are
215 // already properly placed
216 {
217 BTreeNode fatherNode = btn.getFatherNode();// get its father
218 // node
219 int pointer = 0;
220 BTreeNode leftBranch = new BTreeNode(btn.getOrder());
221 BTreeNode rightBranch = new BTreeNode(btn.getOrder());
222 while(pointer < btn.getOrder())
223 {
224 leftBranch.getElements().add(btn.getElements().get(pointer));
225 pointer++;
226 }
227 pointer++;
228 while(pointer < btn.getOrder() * 2 + 1)
229 {
230 rightBranch.getElements().add(btn.getElements().get(pointer));
231 pointer++;
232 }
233 if(btn.getChildrenNodes() != null)// not leaf
234 {
235 pointer = 0;
236 ArrayList<BTreeNode> leftChildren = new ArrayList<BTreeNode>();
237 while(pointer <= btn.getOrder())
238 {
239 BTreeNode child = btn.getChildrenNodes().get(pointer);
240 leftChildren.add(child);
241 child.setPosition(pointer);
242 child.setFatherNode(leftBranch);
243 pointer++;
244 }
245 leftBranch.setChildrenNodes(leftChildren);
246 ArrayList<BTreeNode> rightChildren = new ArrayList<BTreeNode>();
247 while(pointer <= btn.getOrder() * 2 + 1)
248 {
249 BTreeNode child = btn.getChildrenNodes().get(pointer);
250 rightChildren.add(child);
251 child.setPosition(pointer - btn.getOrder() - 1);
252 child.setFatherNode(rightBranch);
253 pointer++;
254 }
255 rightBranch.setChildrenNodes(rightChildren);
256 }
257 if(fatherNode == null)// reached the root
258 {
259 BTreeNode newNode = new BTreeNode(btn.getOrder());
260 newNode.getElements().add(btn.getElements().get(btn.getOrder()));
261 ArrayList<BTreeNode> children = new ArrayList<BTreeNode>();
262 children.add(leftBranch);
263 children.add(rightBranch);
264 leftBranch.setFatherNode(newNode);
265 rightBranch.setFatherNode(newNode);
266 leftBranch.setPosition(0);
267 rightBranch.setPosition(1);
268 newNode.setChildrenNodes(children);
269 this.root = newNode;
270 }
271 else
272 // not the root
273 {
274 ArrayList<Comparable> currentElements = fatherNode.getElements();
275 if(btn.getPosition() == btn.getOrder() * 2)
276 {
277 currentElements.add(btn.getElements().get(btn.getOrder()));
278 fatherNode.getChildrenNodes().remove(btn.getPosition());
279 fatherNode.getChildrenNodes().add(leftBranch);
280 fatherNode.getChildrenNodes().add(rightBranch);
281 leftBranch.setFatherNode(fatherNode);
282 rightBranch.setFatherNode(fatherNode);
283 for(int i = 0; i < fatherNode.getChildrenNodes().size(); i++)
284 {
285 fatherNode.getChildrenNodes().get(i).setPosition(i);
286 }
287 }
288 else
289 {
290 currentElements.add(btn.getPosition(), btn.getElements().get(
291 btn.getOrder()));
292 fatherNode.getChildrenNodes().remove(btn.getPosition());
293 fatherNode.getChildrenNodes()
294 .add(btn.getPosition(), leftBranch);
295 fatherNode.getChildrenNodes().add(btn.getPosition() + 1,
296 rightBranch);
297 leftBranch.setFatherNode(fatherNode);
298 rightBranch.setFatherNode(fatherNode);
299 for(int i = 0; i < fatherNode.getChildrenNodes().size(); i++)
300 {
301 fatherNode.getChildrenNodes().get(i).setPosition(i);
302 }
303 }
304 }
305 }
306
307 private void checkAndSplit(BTreeNode btn)
308 {
309 if(btn.getCount() >= btn.getOrder() * 2 + 1)// need to split
310 {
311 split(btn);
312 if(btn.getFatherNode() != null)
313 {
314 checkAndSplit(btn.getFatherNode());
315 }
316 }
317 }
318
319 @SuppressWarnings("unchecked")
320 private void addToLeaf(BTreeNode btn, Comparable o)
321 {
322 if(btn.getElements().contains(o))
323 {
324 return;
325 }
326 if(btn.getChildrenNodes() == null)// leaf
327 {
328 btn.getElements().add(o);
329 Collections.sort(btn.getElements());// sort the elements in the
330 // leaf
331 checkAndSplit(btn);
332 }
333 else
334 // not leaf, add to its proper sub node
335 {
336 int pointer = 0;
337 while(pointer < btn.getElements().size())
338 {
339 if(o.compareTo(btn.getElements().get(pointer)) < 0)// found it
340 {
341 break;
342 }
343 pointer++;
344 }
345 addToLeaf(btn.getChildrenNodes().get(pointer), o);
346 }
347 }
348
349 @SuppressWarnings("unchecked")
350 private Object findNode(BTreeNode btn, Comparable o)
351 {
352 int index = -1;
353 ArrayList<Comparable> al = btn.getElements();
354 for(int i = 0; i < al.size(); i++)
355 {
356 if(o.compareTo(al.get(i)) == 0)
357 {
358 index = i;
359 break;
360 }
361 }
362 if(index == -1)// can not find it
363 {
364 if(btn.getChildrenNodes() == null)// leaf
365 {
366 return null;
367 }
368 else
369 // not leaf, add to its proper sub node
370 {
371 int pointer = 0;
372 while(pointer < btn.getElements().size())
373 {
374 if(o.compareTo(btn.getElements().get(pointer)) < 0)// found
375 // it's sub node
376 {
377 break;
378 }
379 pointer++;
380 }
381 return findNode(btn.getChildrenNodes().get(pointer), o);
382 }
383 }
384 else
385 {
386 return btn.getElements().get(index);
387 }
388 }
389
390 /*
391 * (non-Javadoc)
392 *
393 * @see bTree.IBTree#find(java.lang.Comparable)
394 */
395 @SuppressWarnings("unchecked")
396 @Override
397 public Object find(Comparable o)
398 {
399 if(this.root == null)
400 {
401 return null;
402 }
403 else
404 {
405 return findNode(this.root, o);
406 }
407 }
408
409 /*
410 * (non-Javadoc)
411 *
412 * @see bTree.IBTree#iterator()
413 */
414 @SuppressWarnings("unchecked")
415 @Override
416 public Iterator iterator()
417 {
418 ArrayList<Comparable> al = new ArrayList<Comparable>();
419 fill(al, this);
420 return al.iterator();
421 }
422
423 @SuppressWarnings("unchecked")
424 private void fill(ArrayList<Comparable> al, BTree bt)
425 {
426 if(bt.root == null)
427 {
428 return;
429 }
430 fill(al, bt.root);
431 }
432
433 @SuppressWarnings("unchecked")
434 private void fill(ArrayList<Comparable> al, BTreeNode btn)
435 {
436 if(btn.getChildrenNodes() == null)// leaf
437 {
438 for(int i = 0; i < btn.getElements().size(); i++)
439 {
440 al.add(btn.getElements().get(i));
441 }
442 }
443 else
444 {
445 int pointer = 0;
446 while(pointer < btn.getElements().size())
447 {
448 fill(al, btn.getChildrenNodes().get(pointer));
449 al.add(btn.getElements().get(pointer));
450 pointer++;
451 }
452 fill(al, btn.getChildrenNodes().get(pointer));
453 }
454 }
455
456 /*
457 * (non-Javadoc)
458 *
459 * @see bTree.IBTree#remove(java.lang.Comparable)
460 */
461 @SuppressWarnings("unchecked")
462 @Override
463 public Object remove(Comparable o)
464 {
465 if(this.root == null)
466 {
467 return null;
468 }
469 Container original = new Container();
470 findOriginalNode(this.root, o, original);
471 if(original.getBtn() == null)
472 {
473 return null;
474 }
475 Object object = original.getBtn().getElements().get(
476 original.getPosition());
477 if(original.getBtn().getChildrenNodes() == null)// leaf,no need to swap
478 {
479 deleteOneElementFromTheLeaf(original);
480 }
481 else
482 // not leaf,swap them,then delete the one at leaf
483 {
484 Container smallest = new Container();
485 findSmallestNode(original.getBtn().getChildrenNodes().get(
486 original.getPosition() + 1), smallest);
487 // swap them
488 Comparable temp = original.getBtn().getElements().get(
489 original.getPosition());
490 original.getBtn().getElements()
491 .set(
492 original.getPosition(),
493 smallest.getBtn().getElements().get(
494 smallest.getPosition()));
495 smallest.getBtn().getElements().set(smallest.getPosition(), temp);
496 deleteOneElementFromTheLeaf(smallest);
497 }
498 return object;
499 }
500
501 @SuppressWarnings("unchecked")
502 private void deleteOneElementFromTheLeaf(Container c)
503 {
504 BTreeNode btn = c.getBtn();
505 if(btn.getElements().size() <= btn.getOrder())// less than order+1,
506 {
507 BTreeNode fatherNode = btn.getFatherNode();
508 if(fatherNode == null)// it is also root
509 {
510 if(btn.getElements().size() == 1)
511 {
512 this.root = null;
513 }
514 else
515 {
516 btn.getElements().remove(c.getPosition());
517 }
518 return;
519 }
520 else
521 {
522 if(fatherNode.getElements().size() == 1)// only one element,need
523 // grand
524 {
525 Comparable add = fatherNode.getElements().get(0);
526 BTreeNode grandNode = fatherNode.getFatherNode();
527 if(grandNode == null)// father node is the root
528 {
529 if(btn.getPosition() == 0)// other side is at position
530 // 1
531 {
532 fatherNode.getChildrenNodes().get(1).setFatherNode(
533 null);
534 fatherNode.getChildrenNodes().get(1)
535 .setPosition(-1);
536 this.root = fatherNode.getChildrenNodes().get(1);
537 addToLeaf(this.root, add);
538 btn.getElements().remove(c.getPosition());
539 for(int i = 0; i < btn.getElements().size(); i++)
540 {
541 addToLeaf(this.root, btn.getElements().get(i));
542 }
543 }
544 else
545 // other side is at position 0
546 {
547 fatherNode.getChildrenNodes().get(0).setFatherNode(
548 null);
549 fatherNode.getChildrenNodes().get(0)
550 .setPosition(-1);
551 this.root = fatherNode.getChildrenNodes().get(0);
552 addToLeaf(this.root, add);
553 btn.getElements().remove(c.getPosition());
554 for(int i = 0; i < btn.getElements().size(); i++)
555 {
556 addToLeaf(this.root, btn.getElements().get(i));
557 }
558 }
559 }
560 else
561 // father node is not the root
562 {
563 if(btn.getPosition() == 0)// other side is at position
564 // 1
565 {
566 fatherNode.getChildrenNodes().get(1).setFatherNode(
567 grandNode);
568 fatherNode.getChildrenNodes().get(1).setPosition(
569 fatherNode.getPosition());
570 grandNode.getChildrenNodes().set(
571 fatherNode.getPosition(),
572 fatherNode.getChildrenNodes().get(1));
573 addToLeaf(this.root, add);
574 btn.getElements().remove(c.getPosition());
575 for(int i = 0; i < btn.getElements().size(); i++)
576 {
577 addToLeaf(this.root, btn.getElements().get(i));
578 }
579 }
580 else
581 // other side is at position 0
582 {
583 fatherNode.getChildrenNodes().get(0).setFatherNode(
584 grandNode);
585 fatherNode.getChildrenNodes().get(0).setPosition(
586 fatherNode.getPosition());
587 grandNode.getChildrenNodes().set(
588 fatherNode.getPosition(),
589 fatherNode.getChildrenNodes().get(0));
590 addToLeaf(this.root, add);
591 btn.getElements().remove(c.getPosition());
592 for(int i = 0; i < btn.getElements().size(); i++)
593 {
594 addToLeaf(this.root, btn.getElements().get(i));
595 }
596 }
597 }
598 }
599 else
600 // don't need grand
601 {
602 if(btn.getPosition() == 0)
603 {
604 Comparable add = fatherNode.getElements().get(0);
605 fatherNode.getElements().remove(0);
606 fatherNode.getChildrenNodes().remove(0);
607 addToLeaf(this.root, add);
608 btn.getElements().remove(c.getPosition());
609 for(int i = 0; i < btn.getElements().size(); i++)
610 {
611 addToLeaf(this.root, btn.getElements().get(i));
612 }
613 }
614 else
615 {
616 Comparable add = fatherNode.getElements().get(
617 btn.getPosition() - 1);
618 fatherNode.getElements().remove(btn.getPosition() - 1);
619 fatherNode.getChildrenNodes().remove(btn.getPosition());
620 addToLeaf(this.root, add);
621 btn.getElements().remove(c.getPosition());
622 for(int i = 0; i < btn.getElements().size(); i++)
623 {
624 addToLeaf(this.root, btn.getElements().get(i));
625 }
626 }
627 }
628 }
629 }
630 else
631 // many elements left,just delete the one
632 {
633 btn.getElements().remove(c.getPosition());
634 }
635 }
636
637 @SuppressWarnings("unchecked")
638 private void findOriginalNode(BTreeNode btn, Comparable o, Container c)
639 {
640 int index = btn.getElements().indexOf(o);
641 if(index == -1)// can not find it
642 {
643 if(btn.getChildrenNodes() == null)// leaf
644 {
645 return;
646 }
647 else
648 // not leaf
649 {
650 int pointer = 0;
651 while(pointer < btn.getElements().size())
652 {
653 if(o.compareTo(btn.getElements().get(pointer)) < 0)// found
654 // it's sub node
655 {
656 break;
657 }
658 pointer++;
659 }
660 findOriginalNode(btn.getChildrenNodes().get(pointer), o, c);
661 }
662 }
663 else
664 {
665 c.setBtn(btn);
666 c.setPosition(index);
667 }
668 }
669
670 private void findSmallestNode(BTreeNode btn, Container c)
671 {
672 if(btn.getChildrenNodes() == null)// leaf
673 {
674 c.setBtn(btn);
675 c.setPosition(0);
676 }
677 else
678 // not leaf
679 {
680 findSmallestNode(btn.getChildrenNodes().get(0), c);
681 }
682 }
683 /**
684 * Because JAVA doesn't support the useful keywords for parameters: in ref
685 * out(C#) byval byref (VB.NET), have to make an internal class to do it
686 *
687 * @author
688 * @version 1.0
689 */
690 private class Container
691 {
692 private BTreeNode btn;
693 private int position;
694
695 /**
696 * Class attribute getter
697 *
698 * @return the btn
699 */
700 public BTreeNode getBtn()
701 {
702 return this.btn;
703 }
704
705 /**
706 * Class attribute setter
707 *
708 * @param btn the btn to set
709 */
710 public void setBtn(BTreeNode btn)
711 {
712 this.btn = btn;
713 }
714
715 /**
716 * Class attribute getter
717 *
718 * @return the position
719 */
720 public int getPosition()
721 {
722 return this.position;
723 }
724
725 /**
726 * Class attribute setter
727 *
728 * @param position the position to set
729 */
730 public void setPosition(int position)
731 {
732 this.position = position;
733 }
734 }
735
736 /**
737 * Class attribute getter
738 *
739 * @return the order
740 */
741 public int getOrder()
742 {
743 return this.order;
744 }
745
746 /*
747 * (non-Javadoc)
748 *
749 * @see bTree.IBTree#clear()
750 */
751 @Override
752 public void clear()
753 {
754 this.root = null;
755 }
756
757 /*
758 * (non-Javadoc)
759 *
760 * @see bTree.IBTree#isEmpty()
761 */
762 @Override
763 public boolean isEmpty()
764 {
765 return this.root == null;
766 }
767}
768
2
3import java.util.*;
4
5/**
6 * @author
7 * @version 1.0
8 */
9public class BTree implements IBTree
10{
11 /**
12 * Attributes
13 */
14 private static final long serialVersionUID = 1L;
15 private BTreeNode root;
16 private int order;
17
18 /**
19 * Constructor
20 */
21 public BTree(int order)
22 {
23 this.order = order;
24 this.root = null;
25 }
26
27 /**
28 * Constructor
29 */
30 public BTree()
31 {
32 this.order = 3;
33 this.root = null;
34 }
35 /**
36 * private class used as the tree node
37 *
38 * @author
39 * @version 1.0
40 */
41 private class BTreeNode
42 {
43 /**
44 * Attributes
45 */
46 private BTreeNode fatherNode;
47 private ArrayList<BTreeNode> childrenNodes;
48 @SuppressWarnings("unchecked")
49 private ArrayList<Comparable> elements;
50 private int order;
51 private int position;
52
53 @SuppressWarnings("unchecked")
54 public BTreeNode(int order, Comparable element)
55 {
56 this.order = order;
57 this.elements = new ArrayList<Comparable>();
58 elements.add(element);
59 this.childrenNodes = null;
60 this.fatherNode = null;
61 this.position = -1;
62 }
63
64 @SuppressWarnings("unchecked")
65 public BTreeNode(int order)
66 {
67 this.order = order;
68 this.elements = new ArrayList<Comparable>();
69 this.childrenNodes = null;
70 this.fatherNode = null;
71 this.position = -1;
72 }
73
74 /**
75 * Class attribute getter
76 *
77 * @return the position
78 */
79 public int getPosition()
80 {
81 return this.position;
82 }
83
84 /**
85 * Class attribute setter
86 *
87 * @param position the position to set
88 */
89 public void setPosition(int position)
90 {
91 this.position = position;
92 }
93
94 /**
95 * Class attribute getter
96 *
97 * @return the order
98 */
99 public int getOrder()
100 {
101 return this.order;
102 }
103
104 /**
105 * Class attribute setter
106 *
107 * @param order the order to set
108 */
109 public void setOrder(int order)
110 {
111 this.order = order;
112 }
113
114 /**
115 * Class attribute getter
116 *
117 * @return the count
118 */
119 public int getCount()
120 {
121 return this.elements.size();
122 }
123
124 /**
125 * Class attribute getter
126 *
127 * @return the fatherNode
128 */
129 public BTreeNode getFatherNode()
130 {
131 return this.fatherNode;
132 }
133
134 /**
135 * Class attribute setter
136 *
137 * @param fatherNode the fatherNode to set
138 */
139 public void setFatherNode(BTreeNode fatherNode)
140 {
141 this.fatherNode = fatherNode;
142 }
143
144 /**
145 * Class attribute getter
146 *
147 * @return the childrenNodes
148 */
149 public ArrayList<BTreeNode> getChildrenNodes()
150 {
151 return this.childrenNodes;
152 }
153
154 /**
155 * Class attribute setter
156 *
157 * @param childrenNodes the childrenNodes to set
158 */
159 public void setChildrenNodes(ArrayList<BTreeNode> childrenNodes)
160 {
161 this.childrenNodes = childrenNodes;
162 }
163
164 /**
165 * Class attribute getter
166 *
167 * @return the elements
168 */
169 @SuppressWarnings("unchecked")
170 public ArrayList<Comparable> getElements()
171 {
172 return this.elements;
173 }
174
175 /**
176 * Class attribute setter
177 *
178 * @param elements the elements to set
179 */
180 @SuppressWarnings("unchecked")
181 public void setElements(ArrayList<Comparable> elements)
182 {
183 this.elements = elements;
184 }
185 }
186
187 /*
188 * (non-Javadoc)
189 *
190 * @see bTree.IBTree#add(java.lang.Comparable)
191 */
192 @SuppressWarnings("unchecked")
193 @Override
194 public void add(Comparable o)
195 {
196 Object object = find(o);
197 if(object != null)
198 {
199 return;
200 }
201 if(this.root == null)// first element
202 {
203 BTreeNode btn = new BTreeNode(this.order, o);
204 this.root = btn;
205 }
206 else
207 // more than one element
208 {
209 addToLeaf(this.root, o);
210 }
211 }
212
213 @SuppressWarnings("unchecked")
214 private void split(BTreeNode btn)// when sub nodes and elements are
215 // already properly placed
216 {
217 BTreeNode fatherNode = btn.getFatherNode();// get its father
218 // node
219 int pointer = 0;
220 BTreeNode leftBranch = new BTreeNode(btn.getOrder());
221 BTreeNode rightBranch = new BTreeNode(btn.getOrder());
222 while(pointer < btn.getOrder())
223 {
224 leftBranch.getElements().add(btn.getElements().get(pointer));
225 pointer++;
226 }
227 pointer++;
228 while(pointer < btn.getOrder() * 2 + 1)
229 {
230 rightBranch.getElements().add(btn.getElements().get(pointer));
231 pointer++;
232 }
233 if(btn.getChildrenNodes() != null)// not leaf
234 {
235 pointer = 0;
236 ArrayList<BTreeNode> leftChildren = new ArrayList<BTreeNode>();
237 while(pointer <= btn.getOrder())
238 {
239 BTreeNode child = btn.getChildrenNodes().get(pointer);
240 leftChildren.add(child);
241 child.setPosition(pointer);
242 child.setFatherNode(leftBranch);
243 pointer++;
244 }
245 leftBranch.setChildrenNodes(leftChildren);
246 ArrayList<BTreeNode> rightChildren = new ArrayList<BTreeNode>();
247 while(pointer <= btn.getOrder() * 2 + 1)
248 {
249 BTreeNode child = btn.getChildrenNodes().get(pointer);
250 rightChildren.add(child);
251 child.setPosition(pointer - btn.getOrder() - 1);
252 child.setFatherNode(rightBranch);
253 pointer++;
254 }
255 rightBranch.setChildrenNodes(rightChildren);
256 }
257 if(fatherNode == null)// reached the root
258 {
259 BTreeNode newNode = new BTreeNode(btn.getOrder());
260 newNode.getElements().add(btn.getElements().get(btn.getOrder()));
261 ArrayList<BTreeNode> children = new ArrayList<BTreeNode>();
262 children.add(leftBranch);
263 children.add(rightBranch);
264 leftBranch.setFatherNode(newNode);
265 rightBranch.setFatherNode(newNode);
266 leftBranch.setPosition(0);
267 rightBranch.setPosition(1);
268 newNode.setChildrenNodes(children);
269 this.root = newNode;
270 }
271 else
272 // not the root
273 {
274 ArrayList<Comparable> currentElements = fatherNode.getElements();
275 if(btn.getPosition() == btn.getOrder() * 2)
276 {
277 currentElements.add(btn.getElements().get(btn.getOrder()));
278 fatherNode.getChildrenNodes().remove(btn.getPosition());
279 fatherNode.getChildrenNodes().add(leftBranch);
280 fatherNode.getChildrenNodes().add(rightBranch);
281 leftBranch.setFatherNode(fatherNode);
282 rightBranch.setFatherNode(fatherNode);
283 for(int i = 0; i < fatherNode.getChildrenNodes().size(); i++)
284 {
285 fatherNode.getChildrenNodes().get(i).setPosition(i);
286 }
287 }
288 else
289 {
290 currentElements.add(btn.getPosition(), btn.getElements().get(
291 btn.getOrder()));
292 fatherNode.getChildrenNodes().remove(btn.getPosition());
293 fatherNode.getChildrenNodes()
294 .add(btn.getPosition(), leftBranch);
295 fatherNode.getChildrenNodes().add(btn.getPosition() + 1,
296 rightBranch);
297 leftBranch.setFatherNode(fatherNode);
298 rightBranch.setFatherNode(fatherNode);
299 for(int i = 0; i < fatherNode.getChildrenNodes().size(); i++)
300 {
301 fatherNode.getChildrenNodes().get(i).setPosition(i);
302 }
303 }
304 }
305 }
306
307 private void checkAndSplit(BTreeNode btn)
308 {
309 if(btn.getCount() >= btn.getOrder() * 2 + 1)// need to split
310 {
311 split(btn);
312 if(btn.getFatherNode() != null)
313 {
314 checkAndSplit(btn.getFatherNode());
315 }
316 }
317 }
318
319 @SuppressWarnings("unchecked")
320 private void addToLeaf(BTreeNode btn, Comparable o)
321 {
322 if(btn.getElements().contains(o))
323 {
324 return;
325 }
326 if(btn.getChildrenNodes() == null)// leaf
327 {
328 btn.getElements().add(o);
329 Collections.sort(btn.getElements());// sort the elements in the
330 // leaf
331 checkAndSplit(btn);
332 }
333 else
334 // not leaf, add to its proper sub node
335 {
336 int pointer = 0;
337 while(pointer < btn.getElements().size())
338 {
339 if(o.compareTo(btn.getElements().get(pointer)) < 0)// found it
340 {
341 break;
342 }
343 pointer++;
344 }
345 addToLeaf(btn.getChildrenNodes().get(pointer), o);
346 }
347 }
348
349 @SuppressWarnings("unchecked")
350 private Object findNode(BTreeNode btn, Comparable o)
351 {
352 int index = -1;
353 ArrayList<Comparable> al = btn.getElements();
354 for(int i = 0; i < al.size(); i++)
355 {
356 if(o.compareTo(al.get(i)) == 0)
357 {
358 index = i;
359 break;
360 }
361 }
362 if(index == -1)// can not find it
363 {
364 if(btn.getChildrenNodes() == null)// leaf
365 {
366 return null;
367 }
368 else
369 // not leaf, add to its proper sub node
370 {
371 int pointer = 0;
372 while(pointer < btn.getElements().size())
373 {
374 if(o.compareTo(btn.getElements().get(pointer)) < 0)// found
375 // it's sub node
376 {
377 break;
378 }
379 pointer++;
380 }
381 return findNode(btn.getChildrenNodes().get(pointer), o);
382 }
383 }
384 else
385 {
386 return btn.getElements().get(index);
387 }
388 }
389
390 /*
391 * (non-Javadoc)
392 *
393 * @see bTree.IBTree#find(java.lang.Comparable)
394 */
395 @SuppressWarnings("unchecked")
396 @Override
397 public Object find(Comparable o)
398 {
399 if(this.root == null)
400 {
401 return null;
402 }
403 else
404 {
405 return findNode(this.root, o);
406 }
407 }
408
409 /*
410 * (non-Javadoc)
411 *
412 * @see bTree.IBTree#iterator()
413 */
414 @SuppressWarnings("unchecked")
415 @Override
416 public Iterator iterator()
417 {
418 ArrayList<Comparable> al = new ArrayList<Comparable>();
419 fill(al, this);
420 return al.iterator();
421 }
422
423 @SuppressWarnings("unchecked")
424 private void fill(ArrayList<Comparable> al, BTree bt)
425 {
426 if(bt.root == null)
427 {
428 return;
429 }
430 fill(al, bt.root);
431 }
432
433 @SuppressWarnings("unchecked")
434 private void fill(ArrayList<Comparable> al, BTreeNode btn)
435 {
436 if(btn.getChildrenNodes() == null)// leaf
437 {
438 for(int i = 0; i < btn.getElements().size(); i++)
439 {
440 al.add(btn.getElements().get(i));
441 }
442 }
443 else
444 {
445 int pointer = 0;
446 while(pointer < btn.getElements().size())
447 {
448 fill(al, btn.getChildrenNodes().get(pointer));
449 al.add(btn.getElements().get(pointer));
450 pointer++;
451 }
452 fill(al, btn.getChildrenNodes().get(pointer));
453 }
454 }
455
456 /*
457 * (non-Javadoc)
458 *
459 * @see bTree.IBTree#remove(java.lang.Comparable)
460 */
461 @SuppressWarnings("unchecked")
462 @Override
463 public Object remove(Comparable o)
464 {
465 if(this.root == null)
466 {
467 return null;
468 }
469 Container original = new Container();
470 findOriginalNode(this.root, o, original);
471 if(original.getBtn() == null)
472 {
473 return null;
474 }
475 Object object = original.getBtn().getElements().get(
476 original.getPosition());
477 if(original.getBtn().getChildrenNodes() == null)// leaf,no need to swap
478 {
479 deleteOneElementFromTheLeaf(original);
480 }
481 else
482 // not leaf,swap them,then delete the one at leaf
483 {
484 Container smallest = new Container();
485 findSmallestNode(original.getBtn().getChildrenNodes().get(
486 original.getPosition() + 1), smallest);
487 // swap them
488 Comparable temp = original.getBtn().getElements().get(
489 original.getPosition());
490 original.getBtn().getElements()
491 .set(
492 original.getPosition(),
493 smallest.getBtn().getElements().get(
494 smallest.getPosition()));
495 smallest.getBtn().getElements().set(smallest.getPosition(), temp);
496 deleteOneElementFromTheLeaf(smallest);
497 }
498 return object;
499 }
500
501 @SuppressWarnings("unchecked")
502 private void deleteOneElementFromTheLeaf(Container c)
503 {
504 BTreeNode btn = c.getBtn();
505 if(btn.getElements().size() <= btn.getOrder())// less than order+1,
506 {
507 BTreeNode fatherNode = btn.getFatherNode();
508 if(fatherNode == null)// it is also root
509 {
510 if(btn.getElements().size() == 1)
511 {
512 this.root = null;
513 }
514 else
515 {
516 btn.getElements().remove(c.getPosition());
517 }
518 return;
519 }
520 else
521 {
522 if(fatherNode.getElements().size() == 1)// only one element,need
523 // grand
524 {
525 Comparable add = fatherNode.getElements().get(0);
526 BTreeNode grandNode = fatherNode.getFatherNode();
527 if(grandNode == null)// father node is the root
528 {
529 if(btn.getPosition() == 0)// other side is at position
530 // 1
531 {
532 fatherNode.getChildrenNodes().get(1).setFatherNode(
533 null);
534 fatherNode.getChildrenNodes().get(1)
535 .setPosition(-1);
536 this.root = fatherNode.getChildrenNodes().get(1);
537 addToLeaf(this.root, add);
538 btn.getElements().remove(c.getPosition());
539 for(int i = 0; i < btn.getElements().size(); i++)
540 {
541 addToLeaf(this.root, btn.getElements().get(i));
542 }
543 }
544 else
545 // other side is at position 0
546 {
547 fatherNode.getChildrenNodes().get(0).setFatherNode(
548 null);
549 fatherNode.getChildrenNodes().get(0)
550 .setPosition(-1);
551 this.root = fatherNode.getChildrenNodes().get(0);
552 addToLeaf(this.root, add);
553 btn.getElements().remove(c.getPosition());
554 for(int i = 0; i < btn.getElements().size(); i++)
555 {
556 addToLeaf(this.root, btn.getElements().get(i));
557 }
558 }
559 }
560 else
561 // father node is not the root
562 {
563 if(btn.getPosition() == 0)// other side is at position
564 // 1
565 {
566 fatherNode.getChildrenNodes().get(1).setFatherNode(
567 grandNode);
568 fatherNode.getChildrenNodes().get(1).setPosition(
569 fatherNode.getPosition());
570 grandNode.getChildrenNodes().set(
571 fatherNode.getPosition(),
572 fatherNode.getChildrenNodes().get(1));
573 addToLeaf(this.root, add);
574 btn.getElements().remove(c.getPosition());
575 for(int i = 0; i < btn.getElements().size(); i++)
576 {
577 addToLeaf(this.root, btn.getElements().get(i));
578 }
579 }
580 else
581 // other side is at position 0
582 {
583 fatherNode.getChildrenNodes().get(0).setFatherNode(
584 grandNode);
585 fatherNode.getChildrenNodes().get(0).setPosition(
586 fatherNode.getPosition());
587 grandNode.getChildrenNodes().set(
588 fatherNode.getPosition(),
589 fatherNode.getChildrenNodes().get(0));
590 addToLeaf(this.root, add);
591 btn.getElements().remove(c.getPosition());
592 for(int i = 0; i < btn.getElements().size(); i++)
593 {
594 addToLeaf(this.root, btn.getElements().get(i));
595 }
596 }
597 }
598 }
599 else
600 // don't need grand
601 {
602 if(btn.getPosition() == 0)
603 {
604 Comparable add = fatherNode.getElements().get(0);
605 fatherNode.getElements().remove(0);
606 fatherNode.getChildrenNodes().remove(0);
607 addToLeaf(this.root, add);
608 btn.getElements().remove(c.getPosition());
609 for(int i = 0; i < btn.getElements().size(); i++)
610 {
611 addToLeaf(this.root, btn.getElements().get(i));
612 }
613 }
614 else
615 {
616 Comparable add = fatherNode.getElements().get(
617 btn.getPosition() - 1);
618 fatherNode.getElements().remove(btn.getPosition() - 1);
619 fatherNode.getChildrenNodes().remove(btn.getPosition());
620 addToLeaf(this.root, add);
621 btn.getElements().remove(c.getPosition());
622 for(int i = 0; i < btn.getElements().size(); i++)
623 {
624 addToLeaf(this.root, btn.getElements().get(i));
625 }
626 }
627 }
628 }
629 }
630 else
631 // many elements left,just delete the one
632 {
633 btn.getElements().remove(c.getPosition());
634 }
635 }
636
637 @SuppressWarnings("unchecked")
638 private void findOriginalNode(BTreeNode btn, Comparable o, Container c)
639 {
640 int index = btn.getElements().indexOf(o);
641 if(index == -1)// can not find it
642 {
643 if(btn.getChildrenNodes() == null)// leaf
644 {
645 return;
646 }
647 else
648 // not leaf
649 {
650 int pointer = 0;
651 while(pointer < btn.getElements().size())
652 {
653 if(o.compareTo(btn.getElements().get(pointer)) < 0)// found
654 // it's sub node
655 {
656 break;
657 }
658 pointer++;
659 }
660 findOriginalNode(btn.getChildrenNodes().get(pointer), o, c);
661 }
662 }
663 else
664 {
665 c.setBtn(btn);
666 c.setPosition(index);
667 }
668 }
669
670 private void findSmallestNode(BTreeNode btn, Container c)
671 {
672 if(btn.getChildrenNodes() == null)// leaf
673 {
674 c.setBtn(btn);
675 c.setPosition(0);
676 }
677 else
678 // not leaf
679 {
680 findSmallestNode(btn.getChildrenNodes().get(0), c);
681 }
682 }
683 /**
684 * Because JAVA doesn't support the useful keywords for parameters: in ref
685 * out(C#) byval byref (VB.NET), have to make an internal class to do it
686 *
687 * @author
688 * @version 1.0
689 */
690 private class Container
691 {
692 private BTreeNode btn;
693 private int position;
694
695 /**
696 * Class attribute getter
697 *
698 * @return the btn
699 */
700 public BTreeNode getBtn()
701 {
702 return this.btn;
703 }
704
705 /**
706 * Class attribute setter
707 *
708 * @param btn the btn to set
709 */
710 public void setBtn(BTreeNode btn)
711 {
712 this.btn = btn;
713 }
714
715 /**
716 * Class attribute getter
717 *
718 * @return the position
719 */
720 public int getPosition()
721 {
722 return this.position;
723 }
724
725 /**
726 * Class attribute setter
727 *
728 * @param position the position to set
729 */
730 public void setPosition(int position)
731 {
732 this.position = position;
733 }
734 }
735
736 /**
737 * Class attribute getter
738 *
739 * @return the order
740 */
741 public int getOrder()
742 {
743 return this.order;
744 }
745
746 /*
747 * (non-Javadoc)
748 *
749 * @see bTree.IBTree#clear()
750 */
751 @Override
752 public void clear()
753 {
754 this.root = null;
755 }
756
757 /*
758 * (non-Javadoc)
759 *
760 * @see bTree.IBTree#isEmpty()
761 */
762 @Override
763 public boolean isEmpty()
764 {
765 return this.root == null;
766 }
767}
768