Skip to content

Commit 5c1e195

Browse files
committed
Merge branch 'master' of https://github.com/xtaci/algorithms
2 parents b17fed8 + 49f09d1 commit 5c1e195

File tree

3 files changed

+92
-31
lines changed

3 files changed

+92
-31
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
Interval tree
4949
Prefix Tree(Trie)
5050
*Suffix Tree(未实现)*
51+
B-Tree
5152

5253
Hash by multiplication
5354
Hash table

include/btree.h

Lines changed: 88 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ namespace alg {
4848
} __attribute__ ((packed));
4949
typedef struct node_t *node;
5050

51+
public:
52+
// node and index
53+
struct nr {
54+
uint32_t offset;
55+
int32_t idx;
56+
};
5157
private:
5258
node m_root;
5359
int fd;
@@ -72,7 +78,7 @@ namespace alg {
7278
close(fd);
7379
}
7480

75-
int32_t Search(int32_t x) {
81+
nr Search(int32_t x) {
7682
return search(m_root, x);
7783
}
7884

@@ -87,6 +93,7 @@ namespace alg {
8793
s->flag &= ~LEAF;
8894
s->flag |= ONDISK; // write to offset 0
8995
s->offset = 0;
96+
s->n = 0;
9097
s->c[0] = m_root->offset;
9198
// free old & set new
9299
free(m_root);
@@ -98,20 +105,30 @@ namespace alg {
98105
}
99106
}
100107

108+
void DeleteKey(int32_t k) {
109+
node x = m_root;
110+
delete_op(m_root, k);
111+
}
112+
101113
private:
102114
/**
103115
* search a key, returns node and index
104116
*/
105-
int32_t search(node x, int32_t k) {
117+
nr search(node x, int32_t k) {
106118
int32_t i = 0;
119+
nr ret;
107120
while (i<x->n && k > x->key[i]) i++;
108121

109-
if (i<x->n && k == x->key[i]) {
110-
return i;
111-
} else if (x->flag & LEAF) {
112-
return -1;
122+
if (i<x->n && k == x->key[i]) { // search in [0,n-1]
123+
ret.offset = x->offset;
124+
ret.idx = i;
125+
return ret;
126+
} else if (x->flag & LEAF) { // leaf, no more childs
127+
ret.offset = 0;
128+
ret.idx = -1;
129+
return ret;
113130
} else {
114-
std::auto_ptr<node_t> xi(READ(x, i));
131+
std::auto_ptr<node_t> xi(READ(x, i)); // in last child
115132
return search(xi.get(), k);
116133
}
117134
}
@@ -121,8 +138,8 @@ namespace alg {
121138
*/
122139
void insert_nonfull(node x, int32_t k) {
123140
int32_t i = x->n-1;
124-
if (x->flag & LEAF) {
125-
while (i>=0 && k <x->key[i]) {
141+
if (x->flag & LEAF) { // insert into leaf
142+
while (i>=0 && k < x->key[i]) { // shift from right to left, when k < key[i]
126143
x->key[i+1] = x->key[i];
127144
i = i - 1;
128145
}
@@ -140,6 +157,8 @@ namespace alg {
140157
if (k > x->key[i]) {
141158
i = i+1;
142159
}
160+
// reload x[i] after split_child(will modify child x[i])
161+
xi = READ(x, i);
143162
}
144163
insert_nonfull(xi, k);
145164
free(xi);
@@ -167,41 +186,87 @@ namespace alg {
167186
std::auto_ptr<node_t> y(READ(x, i));
168187
z->flag &= ~LEAF;
169188
z->flag |= (y->flag & LEAF);
170-
printf("leafz:%x\n", z->flag);
171-
printf("leafy:%x\n", y->flag);
172-
printf("leafx:%x offset:%x\n", x->flag, x->offset);
173189
z->n = T - 1;
174190

175191
int32_t j;
176-
for (j=0;j<T-1;j++) { // init z
192+
for (j=0;j<T-1;j++) { // init z, t-1 keys
177193
z->key[j] = y->key[j+T];
178194
}
179195

180-
if (!(y->flag & LEAF)) {
196+
if (!(y->flag & LEAF)) { // if not leaf, copy childs too.
181197
for (j=0;j<T;j++) {
182198
z->c[j] = y->c[j+T];
183199
}
184200
}
185201

186-
y->n = T-1; // splited y
202+
y->n = T-1; // shrink y to t-1 elements
187203
WRITE(y.get());
188204
WRITE(z.get());
189205

190-
for (j=x->n;j>=i+1;j--) {
191-
x->c[j+1] = x->c[j]; // shift
206+
for (j=x->n;j>=i+1;j--) { // make place for the new child in x
207+
x->c[j+1] = x->c[j];
192208
}
193209

194-
// save z
195-
x->c[i+1] = z->offset;
196-
197-
for (j=x->n-1;j>=i;j--) {
210+
x->c[i+1] = z->offset; // make z the child of x
211+
for (j=x->n-1;j>=i;j--) { // move keys in x
198212
x->key[j+1] = x->key[j];
199213
}
200-
x->key[i] = y->key[T-1];
214+
x->key[i] = y->key[T-1]; // copy the middle element of y into x
201215
x->n = x->n+1;
202216
WRITE(x);
203217
}
204218

219+
/**
220+
* recursion deletion
221+
*/
222+
void delete_op(node x, int32_t k) {
223+
int32_t i;
224+
for (i=0;i<x->n;i++) {
225+
if (x->key[i] == k) { // leaf node, case1
226+
break;
227+
}
228+
}
229+
230+
if (i<x->n && (x->flag & LEAF)) {
231+
int j;
232+
for (j = i;j<x->n-1;j++) { // shift copy
233+
x->key[j] = x->key[j+1];
234+
}
235+
WRITE(x);
236+
} else if (x->key[i] == k) { // non-leaf
237+
if (i = x->n-1 || i == 0) { // outside, case 2c
238+
delete_case3(x);
239+
} else {
240+
node y= READ(x, i-1);
241+
if (y->n >= T) { // case 2a
242+
x->key[i] = y->key[y->n-1]; // subsitute the key with predecessor
243+
delete_op(y, x->key[i]);
244+
free(y);
245+
return;
246+
}
247+
248+
node z = READ(x, i+1);
249+
if (z->n >= T) { // case 2b
250+
x->key[i] = z->key[0];
251+
delete_op(z, x->key[i]);
252+
return;
253+
}
254+
255+
// case 2c:
256+
if (y->n == T-1 && z->n == T-1) {
257+
258+
}
259+
delete_case3(x);
260+
}
261+
}
262+
}
263+
264+
/**
265+
* delete case3
266+
*/
267+
void delete_case3(node x) {
268+
}
269+
205270
/**
206271
* Read a 4K-block from disk, and returns the node struct.
207272
*/
@@ -211,7 +276,7 @@ namespace alg {
211276
read(fd, xi, BLOCKSIZE);
212277
return (node)xi;
213278
}
214-
279+
215280
/**
216281
* update a node struct to file, create if offset is -1.
217282
*/

src/btree_demo.cpp

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,9 @@ int main(void) {
66
BTree x("./btree.dat");
77
int32_t i;
88

9-
/*
10-
for (i=0;i<1024;i++) {
9+
for (i=0;i<100000;i++) {
1110
x.Insert(i);
12-
}
13-
*/
14-
15-
for(i=0;i<1024;i++) {
16-
int32_t r = x.Search(i);
17-
printf("idx[%d]\n", r);
11+
BTree::nr r = x.Search(i);
12+
printf("offset[%x] idx[%d]\n", r.offset, r.idx);
1813
}
1914
}

0 commit comments

Comments
 (0)