b tree的java实现
1
package bTree;
2
3
import java.io.Serializable;
4
import java.util.Iterator;
5
6
/**
7
* Interface for a b tree
8
*
9
* @author
10
* @version 1.0
11
*/
12
public 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
package bTree;2

3
import java.io.Serializable;4
import java.util.Iterator;5

6
/**7
* Interface for a b tree8
* 9
* @author 10
* @version 1.011
*/12
public interface IBTree extends Serializable13
{14
/**15
* Method that will add an node into the b tree16
* 17
* @param o node to add18
*/19
@SuppressWarnings("unchecked")20
public void add(Comparable o);21
22
/**23
* Method that will remove an node from the b tree24
* 25
* @param o node to remove26
* @return object27
*/28
@SuppressWarnings("unchecked")29
public Object remove(Comparable o);30
31
/**32
* Method that will find the element belongs to the specified node33
* 34
* @param o node to find35
* @return object36
*/37
@SuppressWarnings("unchecked")38
public Object find(Comparable o);39
40
/**41
* Method that will return an iterator of the b tree42
* 43
* @return the iterator of the b tree44
*/45
@SuppressWarnings("unchecked")46
public Iterator iterator();47
48
/**49
* Method that will clear the b tree50
*/51
public void clear();52
53
/**54
* Method that will check to see if the b tree is null55
* 56
* @return true if the b tree is null, false if it is not57
*/58
public boolean isEmpty();59
}60

1
package bTree;
2
3
import java.util.*;
4
5
/**
6
* @author
7
* @version 1.0
8
*/
9
public 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
package bTree;2

3
import java.util.*;4

5
/**6
* @author 7
* @version 1.08
*/9
public class BTree implements IBTree10
{11
/**12
* Attributes13
*/14
private static final long serialVersionUID = 1L;15
private BTreeNode root;16
private int order;17
18
/**19
* Constructor20
*/21
public BTree(int order)22
{23
this.order = order;24
this.root = null;25
}26
27
/**28
* Constructor29
*/30
public BTree()31
{32
this.order = 3;33
this.root = null;34
}35
/**36
* private class used as the tree node37
* 38
* @author 39
* @version 1.040
*/41
private class BTreeNode42
{43
/**44
* Attributes45
*/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 getter76
* 77
* @return the position78
*/79
public int getPosition()80
{81
return this.position;82
}83
84
/**85
* Class attribute setter86
* 87
* @param position the position to set88
*/89
public void setPosition(int position)90
{91
this.position = position;92
}93
94
/**95
* Class attribute getter96
* 97
* @return the order98
*/99
public int getOrder()100
{101
return this.order;102
}103
104
/**105
* Class attribute setter106
* 107
* @param order the order to set108
*/109
public void setOrder(int order)110
{111
this.order = order;112
}113
114
/**115
* Class attribute getter116
* 117
* @return the count118
*/119
public int getCount()120
{121
return this.elements.size();122
}123
124
/**125
* Class attribute getter126
* 127
* @return the fatherNode128
*/129
public BTreeNode getFatherNode()130
{131
return this.fatherNode;132
}133
134
/**135
* Class attribute setter136
* 137
* @param fatherNode the fatherNode to set138
*/139
public void setFatherNode(BTreeNode fatherNode)140
{141
this.fatherNode = fatherNode;142
}143
144
/**145
* Class attribute getter146
* 147
* @return the childrenNodes148
*/149
public ArrayList<BTreeNode> getChildrenNodes()150
{151
return this.childrenNodes;152
}153
154
/**155
* Class attribute setter156
* 157
* @param childrenNodes the childrenNodes to set158
*/159
public void setChildrenNodes(ArrayList<BTreeNode> childrenNodes)160
{161
this.childrenNodes = childrenNodes;162
}163
164
/**165
* Class attribute getter166
* 167
* @return the elements168
*/169
@SuppressWarnings("unchecked")170
public ArrayList<Comparable> getElements()171
{172
return this.elements;173
}174
175
/**176
* Class attribute setter177
* 178
* @param elements the elements to set179
*/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
@Override194
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 element202
{203
BTreeNode btn = new BTreeNode(this.order, o);204
this.root = btn;205
}206
else207
// more than one element208
{209
addToLeaf(this.root, o);210
}211
}212
213
@SuppressWarnings("unchecked")214
private void split(BTreeNode btn)// when sub nodes and elements are215
// already properly placed216
{217
BTreeNode fatherNode = btn.getFatherNode();// get its father218
// node219
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 leaf234
{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 root258
{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
else272
// not the root273
{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
else289
{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 split310
{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)// leaf327
{328
btn.getElements().add(o);329
Collections.sort(btn.getElements());// sort the elements in the330
// leaf331
checkAndSplit(btn);332
}333
else334
// not leaf, add to its proper sub node335
{336
int pointer = 0;337
while(pointer < btn.getElements().size())338
{339
if(o.compareTo(btn.getElements().get(pointer)) < 0)// found it340
{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 it363
{364
if(btn.getChildrenNodes() == null)// leaf365
{366
return null;367
}368
else369
// not leaf, add to its proper sub node370
{371
int pointer = 0;372
while(pointer < btn.getElements().size())373
{374
if(o.compareTo(btn.getElements().get(pointer)) < 0)// found375
// it's sub node376
{377
break;378
}379
pointer++;380
}381
return findNode(btn.getChildrenNodes().get(pointer), o);382
}383
}384
else385
{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
@Override397
public Object find(Comparable o)398
{399
if(this.root == null)400
{401
return null;402
}403
else404
{405
return findNode(this.root, o);406
}407
}408
409
/*410
* (non-Javadoc)411
* 412
* @see bTree.IBTree#iterator()413
*/414
@SuppressWarnings("unchecked")415
@Override416
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)// leaf437
{438
for(int i = 0; i < btn.getElements().size(); i++)439
{440
al.add(btn.getElements().get(i));441
}442
}443
else444
{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
@Override463
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 swap478
{479
deleteOneElementFromTheLeaf(original);480
}481
else482
// not leaf,swap them,then delete the one at leaf483
{484
Container smallest = new Container();485
findSmallestNode(original.getBtn().getChildrenNodes().get(486
original.getPosition() + 1), smallest);487
// swap them488
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 root509
{510
if(btn.getElements().size() == 1)511
{512
this.root = null;513
}514
else515
{516
btn.getElements().remove(c.getPosition());517
}518
return;519
}520
else521
{522
if(fatherNode.getElements().size() == 1)// only one element,need523
// grand524
{525
Comparable add = fatherNode.getElements().get(0);526
BTreeNode grandNode = fatherNode.getFatherNode();527
if(grandNode == null)// father node is the root528
{529
if(btn.getPosition() == 0)// other side is at position530
// 1531
{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
else545
// other side is at position 0546
{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
else561
// father node is not the root562
{563
if(btn.getPosition() == 0)// other side is at position564
// 1565
{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
else581
// other side is at position 0582
{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
else600
// don't need grand601
{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
else615
{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
else631
// many elements left,just delete the one632
{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 it642
{643
if(btn.getChildrenNodes() == null)// leaf644
{645
return;646
}647
else648
// not leaf649
{650
int pointer = 0;651
while(pointer < btn.getElements().size())652
{653
if(o.compareTo(btn.getElements().get(pointer)) < 0)// found654
// it's sub node655
{656
break;657
}658
pointer++;659
}660
findOriginalNode(btn.getChildrenNodes().get(pointer), o, c);661
}662
}663
else664
{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)// leaf673
{674
c.setBtn(btn);675
c.setPosition(0);676
}677
else678
// not leaf679
{680
findSmallestNode(btn.getChildrenNodes().get(0), c);681
}682
}683
/**684
* Because JAVA doesn't support the useful keywords for parameters: in ref685
* out(C#) byval byref (VB.NET), have to make an internal class to do it686
* 687
* @author 688
* @version 1.0689
*/690
private class Container691
{692
private BTreeNode btn;693
private int position;694
695
/**696
* Class attribute getter697
* 698
* @return the btn699
*/700
public BTreeNode getBtn()701
{702
return this.btn;703
}704
705
/**706
* Class attribute setter707
* 708
* @param btn the btn to set709
*/710
public void setBtn(BTreeNode btn)711
{712
this.btn = btn;713
}714
715
/**716
* Class attribute getter717
* 718
* @return the position719
*/720
public int getPosition()721
{722
return this.position;723
}724
725
/**726
* Class attribute setter727
* 728
* @param position the position to set729
*/730
public void setPosition(int position)731
{732
this.position = position;733
}734
}735
736
/**737
* Class attribute getter738
* 739
* @return the order740
*/741
public int getOrder()742
{743
return this.order;744
}745
746
/*747
* (non-Javadoc)748
* 749
* @see bTree.IBTree#clear()750
*/751
@Override752
public void clear()753
{754
this.root = null;755
}756
757
/*758
* (non-Javadoc)759
* 760
* @see bTree.IBTree#isEmpty()761
*/762
@Override763
public boolean isEmpty()764
{765
return this.root == null;766
}767
}768




浙公网安备 33010602011771号