1
1
package ssj .algorithm .collections ;
2
2
3
+ import com .google .common .base .Preconditions ;
3
4
import ssj .algorithm .SearchTree ;
5
+ import ssj .algorithm .lang .Tuple2 ;
4
6
5
7
import java .util .Iterator ;
6
8
7
9
/**
10
+ * 在B树中支持重复元素比较复杂,因此暂时不要把重复元素插入进去
8
11
* Created by shenshijun on 15/2/5.
9
12
*/
10
13
public class BTree <T extends Comparable <? super T >> implements SearchTree <T > {
11
- //TODO 完成B树
14
+ private static final int DEFAULT_DEGREE = 4 ;
15
+ private int tree_degree ;
16
+ private BTreeNode <T > root ;
17
+ private int tree_size ;
18
+
19
+ private BTree (int degree ) {
20
+ Preconditions .checkArgument (degree >= 2 );
21
+ tree_degree = degree ;
22
+ tree_size = 0 ;
23
+ root = new BTreeNode <>(tree_degree );
24
+ }
25
+
26
+ public static <T extends Comparable <? super T >> BTree <T > degreeOf (int degree ) {
27
+ return new BTree <>(degree );
28
+ }
29
+
30
+ public static <T extends Comparable <? super T >> BTree <T > defaultDegree () {
31
+ return new BTree <>(DEFAULT_DEGREE );
32
+ }
33
+
12
34
@ Override
13
35
public void add (T ele ) {
36
+ Preconditions .checkNotNull (ele );
37
+
38
+ BTreeNode <T > leaf_node = root ;
39
+ for (BTreeNode <T > cur_node = root ; cur_node != null && !cur_node .isValueEmpty (); ) {
40
+ leaf_node = cur_node ;
41
+ for (int i = 1 ; i < cur_node .size (); i += 2 ) {
42
+ int cmp_res = cur_node .getValue (i ).compareTo (ele );
43
+ //如果非空,那么是最后一个子节点
44
+ if (cmp_res < 0 && i == cur_node .size () - 2 ) {
45
+ cur_node = cur_node .getChild (i + 1 );
46
+ break ;
47
+ } else if (cmp_res >= 0 ) {
48
+ cur_node = cur_node .getChild (i - 1 );
49
+ break ;
50
+ }
51
+ }
52
+
53
+ if (leaf_node .isValueFull () && cur_node != null ) {
54
+ splitNode (leaf_node , null );
55
+ }
56
+ }
57
+
58
+ if (leaf_node .isValueFull ()) {
59
+ splitNode (leaf_node , ele );
60
+ } else {
61
+ leaf_node .appendValue (ele );
62
+ }
63
+ tree_size ++;
64
+ }
65
+
66
+ private Tuple2 <BTreeNode <T >, BTreeNode <T >> splitNode (BTreeNode <T > node , T insert_ele ) {
67
+ Preconditions .checkNotNull (node );
68
+
69
+ BTreeNode <T > right_node = new BTreeNode <>(tree_degree );
70
+ BTreeNode <T > parent_node = node .getParent ();
71
+ if (node == root ) {
72
+ parent_node = new BTreeNode <>(tree_degree );
73
+ root = parent_node ;
74
+ }
75
+ right_node .setParent (parent_node );
14
76
77
+ //中间节点插入父节点,子节点的中点在degree-1。因为从0开始计数,所以需要减一
78
+ int mid_index = parent_node .appendValue (node .deleteValue (node .size () / 2 ));
79
+ parent_node .setChild (mid_index - 1 , node );
80
+ parent_node .setChild (mid_index + 1 , right_node );
81
+
82
+ //把一半元素移动到新到节点中
83
+ for (int i = node .size () / 2 ; i < node .size (); i += 1 ) {
84
+ if (i % 2 == 0 ) {
85
+ right_node .setChild (i - node .size () / 2 , node .deleteChild (i ));
86
+ } else {
87
+ right_node .setValue (i - node .size () / 2 , node .deleteValue (i ));
88
+ }
89
+ }
90
+
91
+ if (insert_ele != null ) {
92
+ if (parent_node .getValue (mid_index ).compareTo (insert_ele ) > 0 ) {
93
+ right_node .appendValue (insert_ele );
94
+ } else {
95
+ node .appendValue (insert_ele );
96
+ }
97
+ }
98
+
99
+ return new Tuple2 <>(node , right_node );
15
100
}
16
101
17
102
@ Override
18
103
public int size () {
19
- return 0 ;
104
+ return tree_size ;
20
105
}
21
106
22
107
@ Override
@@ -54,11 +139,6 @@ public T min() {
54
139
return null ;
55
140
}
56
141
57
- @ Override
58
- public T kthElement (int k ) {
59
- return null ;
60
- }
61
-
62
142
@ Override
63
143
public boolean contains (T ele ) {
64
144
return false ;
@@ -73,4 +153,186 @@ public boolean isBalance() {
73
153
public Iterator <T > iterator () {
74
154
return null ;
75
155
}
156
+
157
+ private static class BTreeNode <T extends Comparable <? super T >> {
158
+ private final int DEGREE ;
159
+ private final int HALF_CAPACITY ;
160
+ private final int CAPACITY ;
161
+ //奇数位置上存储子节点,偶数位置上存储关键字。
162
+ private Object [] values ;
163
+ private BTreeNode <T > parent ;
164
+ private int value_index = -1 ;
165
+
166
+ public BTreeNode (int degree ) {
167
+ this .DEGREE = degree ;
168
+ HALF_CAPACITY = 2 * DEGREE - 1 ;
169
+ CAPACITY = 4 * DEGREE - 1 ;
170
+ }
171
+
172
+ public BTreeNode <T > getParent () {
173
+ return parent ;
174
+ }
175
+
176
+ public void setParent (BTreeNode <T > parent ) {
177
+ this .parent = parent ;
178
+ }
179
+
180
+ private void extend (int expect ) {
181
+ if (expect >= HALF_CAPACITY ) {
182
+ Object [] new_values = new Object [CAPACITY ];
183
+ if (values != null ) {
184
+ System .arraycopy (values , 0 , new_values , 0 , values .length );
185
+ }
186
+ values = new_values ;
187
+ } else if (values == null ) {
188
+ values = new Object [HALF_CAPACITY ];
189
+ }
190
+
191
+ }
192
+
193
+ @ SuppressWarnings ("unchecked" )
194
+ public BTreeNode <T > getChild (int index ) {
195
+ Preconditions .checkPositionIndex (index , CAPACITY );
196
+ Preconditions .checkArgument (index % 2 == 0 , "wrong index" );
197
+
198
+ extend (index );
199
+ return (BTreeNode <T >) values [index ];
200
+ }
201
+
202
+ @ SuppressWarnings ("unchecked" )
203
+ public T getValue (int index ) {
204
+ Preconditions .checkPositionIndex (index , CAPACITY );
205
+ Preconditions .checkArgument (index % 2 == 1 , "wrong index" );
206
+
207
+ extend (index );
208
+ return (T ) values [index ];
209
+ }
210
+
211
+ public int size () {
212
+ extend (1 );
213
+ return values .length ;
214
+ }
215
+
216
+ public boolean isValueFull () {
217
+ return size () == CAPACITY && value_index == CAPACITY - 2 ;
218
+ }
219
+
220
+ public boolean isValueEmpty () {
221
+ return value_index < 0 ;
222
+ }
223
+
224
+ public boolean isChildFull () {
225
+ boolean result = true ;
226
+ for (int i = 0 ; i < size (); i += 2 ) {
227
+ if (values [i ] == null ) {
228
+ result = false ;
229
+ }
230
+ }
231
+ return result ;
232
+ }
233
+
234
+ public boolean isChildEmpty () {
235
+ boolean result = true ;
236
+ for (int i = 1 ; i < size (); i += 2 ) {
237
+ if (values [i ] != null ) {
238
+ result = false ;
239
+ }
240
+ }
241
+ return result ;
242
+ }
243
+
244
+ public boolean addChild (int index , BTreeNode <T > child ) {
245
+ Preconditions .checkPositionIndex (index , CAPACITY );
246
+ Preconditions .checkArgument (index % 2 == 0 , "wrong index" );
247
+ extend (index );
248
+ if (isChildFull ()) return false ;
249
+ for (int i = size () - 1 ; i >= index ; i -= 2 ) {
250
+ if (values [i ] != null ) {
251
+ // values[i] =
252
+ }
253
+ }
254
+
255
+ values [index ] = child ;
256
+ return false ;
257
+ }
258
+
259
+ /**
260
+ * 按照排序的顺序把元素插入数组中
261
+ *
262
+ * @param value
263
+ * @return 插入的位置,这样好确定子节点的位置
264
+ */
265
+ public int appendValue (T value ) {
266
+ if (isValueFull ()) return -1 ;
267
+ extend (value_index + 2 );
268
+
269
+ int last_empty = -1 ;
270
+ //从头开始首先压缩节点,然后再插入
271
+ for (int i = 1 ; i < size (); i += 2 ) {
272
+ if (getValue (i ) == null && last_empty == -1 ) {
273
+ last_empty = i ;
274
+ } else if (last_empty != -1 && getValue (i ) != null ) {
275
+ values [last_empty ] = values [i ];
276
+ values [i ] = null ;
277
+ while (getValue (last_empty ) != null ) {
278
+ last_empty ++;
279
+ }
280
+ }
281
+ }
282
+ value_index = last_empty ;
283
+ //节点为空
284
+ if (last_empty == 1 ) {
285
+ values [last_empty ] = value ;
286
+ value_index = last_empty ;
287
+ return last_empty ;
288
+ }
289
+
290
+ int last_pos = -1 ;
291
+ for (int i = last_empty - 2 ; i > 0 ; i -= 2 ) {
292
+ if (getValue (i ).compareTo (value ) >= 0 ) {
293
+ last_pos = i ;
294
+ values [i + 2 ] = values [i ];
295
+ } else {
296
+ values [i + 2 ] = value ;
297
+ return i + 2 ;
298
+ }
299
+ }
300
+
301
+ if (last_pos > 0 ) {
302
+ values [last_pos ] = value ;
303
+ }
304
+ return -1 ;
305
+
306
+ }
307
+
308
+
309
+ public void setValue (int index , T ele ) {
310
+ Preconditions .checkPositionIndex (index , CAPACITY );
311
+ Preconditions .checkArgument (index % 2 == 1 , "wrong index" );
312
+ extend (index );
313
+
314
+ values [index ] = ele ;
315
+ }
316
+
317
+ public void setChild (int index , BTreeNode <T > child ) {
318
+ Preconditions .checkPositionIndex (index , CAPACITY );
319
+ Preconditions .checkArgument (index % 2 == 0 , "wrong index" );
320
+ extend (index );
321
+
322
+ values [index ] = child ;
323
+ }
324
+
325
+ public T deleteValue (int index ) {
326
+ T result = getValue (index );
327
+ setValue (index , null );
328
+ return result ;
329
+ }
330
+
331
+ public BTreeNode <T > deleteChild (int index ) {
332
+ BTreeNode <T > result = getChild (index );
333
+ setChild (index , null );
334
+ return result ;
335
+ }
336
+
337
+ }
76
338
}
0 commit comments