Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 3605a11

Browse files
B-tree in Java
1 parent 641ec33 commit 3605a11

File tree

5 files changed

+498
-0
lines changed

5 files changed

+498
-0
lines changed

‎Trees/btree/Btree.java

Lines changed: 371 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,371 @@
1+
/*
2+
Copyright (C) Deepali Srivastava - All Rights Reserved
3+
This code is part of DSA course available on CourseGalaxy.com
4+
*/
5+
6+
package btree;
7+
8+
public class Btree
9+
{
10+
private static final int M = 5;
11+
private static final int MAX = M - 1;
12+
private static final int MIN = (int)Math.ceil((double)M / 2) - 1;
13+
14+
private Node root;
15+
16+
public Btree()
17+
{
18+
root = null;
19+
}
20+
21+
public boolean Search(int x)
22+
{
23+
if (Search(x, root) == null)
24+
return false;
25+
return true;
26+
}
27+
28+
private Node Search(int x, Node p)
29+
{
30+
if (p == null) /*Key x not present in the tree*/
31+
return null;
32+
33+
IntHolder n = new IntHolder(0);
34+
if (SearchNode(x, p, n) == true) /* Key x found in node p */
35+
return p;
36+
37+
return Search(x, p.child[n.value]); /* Search in nth child of p */
38+
}
39+
40+
private boolean SearchNode(int x, Node p, IntHolder n)
41+
{
42+
if (x < p.key[1]) /* key x is less than leftmost key */
43+
{
44+
n.value = 0;
45+
return false;
46+
}
47+
48+
n.value = p.numKeys;
49+
while ((x < p.key[n.value]) && n.value > 1)
50+
n.value--;
51+
52+
if (x == p.key[n.value])
53+
return true;
54+
else
55+
return false;
56+
}
57+
58+
public void Inorder()
59+
{
60+
Inorder(root);
61+
}
62+
63+
private void Inorder(Node p)
64+
{
65+
if (p == null)
66+
return;
67+
68+
int i;
69+
for (i = 0; i < p.numKeys; i++)
70+
{
71+
Inorder(p.child[i]);
72+
System.out.print(p.key[i + 1] + " ");
73+
}
74+
Inorder(p.child[i]);
75+
}
76+
77+
public void Display()
78+
{
79+
Display(root, 0);
80+
}
81+
82+
private void Display(Node p, int blanks)
83+
{
84+
if (p != null)
85+
{
86+
int i;
87+
for (i = 1; i <= blanks; i++)
88+
System.out.print(" ");
89+
90+
for (i = 1; i <= p.numKeys; i++)
91+
System.out.print(p.key[i] + " ");
92+
System.out.print("\n");
93+
94+
for (i = 0; i <= p.numKeys; i++)
95+
Display(p.child[i], blanks + 10);
96+
}
97+
}
98+
99+
public void Insert(int x)
100+
{
101+
IntHolder iKey = new IntHolder(0);
102+
NodeHolder iKeyRchild = new NodeHolder(null);
103+
104+
boolean taller = Insert(x, root, iKey, iKeyRchild);
105+
106+
if (taller) /* Height increased by one, new root node has to be created */
107+
{
108+
Node temp = new Node(M);
109+
temp.child[0] = root;
110+
root = temp;
111+
112+
root.numKeys = 1;
113+
root.key[1] = iKey.value;
114+
root.child[1] = iKeyRchild.value;
115+
}
116+
}
117+
118+
119+
private boolean Insert(int x, Node p, IntHolder iKey, NodeHolder iKeyRchild)
120+
{
121+
if (p == null) /*First Base case : key not found*/
122+
{
123+
iKey.value = x;
124+
iKeyRchild.value = null;
125+
return true;
126+
}
127+
128+
IntHolder n = new IntHolder(0);
129+
130+
if (SearchNode(x, p, n) == true) /*Second Base Case : key found*/
131+
{
132+
System.out.println("Key already present in the tree");
133+
return false; /*No need to insert the key*/
134+
}
135+
136+
boolean flag = Insert(x, p.child[n.value], iKey, iKeyRchild);
137+
138+
if (flag == true)
139+
{
140+
if (p.numKeys < MAX)
141+
{
142+
InsertByShift(p, n.value, iKey.value, iKeyRchild.value);
143+
return false; /*Insertion over*/
144+
}
145+
else
146+
{
147+
Split(p, n.value, iKey, iKeyRchild);
148+
return true; /*Insertion not over : Median key yet to be inserted*/
149+
}
150+
}
151+
return false;
152+
}
153+
154+
private void InsertByShift(Node p, int n, int iKey, Node iKeyRchild)
155+
{
156+
for (int i = p.numKeys; i > n; i--)
157+
{
158+
p.key[i+1] = p.key[i];
159+
p.child[i+1] = p.child[i];
160+
}
161+
162+
p.key[n+1] = iKey;
163+
p.child[n+1] = iKeyRchild;
164+
p.numKeys++;
165+
}
166+
167+
private void Split(Node p, int n, IntHolder iKey, NodeHolder iKeyRchild)
168+
{
169+
int i, j;
170+
int lastKey;
171+
Node lastChild;
172+
173+
if (n == MAX)
174+
{
175+
lastKey = iKey.value;
176+
lastChild = iKeyRchild.value;
177+
}
178+
else
179+
{
180+
lastKey = p.key[MAX];
181+
lastChild = p.child[MAX];
182+
183+
for (i = p.numKeys - 1; i > n; i--)
184+
{
185+
p.key[i+1] = p.key[i];
186+
p.child[i+1] = p.child[i];
187+
}
188+
189+
p.key[i+1] = iKey.value;
190+
p.child[i+1] = iKeyRchild.value;
191+
}
192+
193+
int d = (M + 1) / 2;
194+
int medianKey = p.key[d];
195+
Node newNode = new Node(M);
196+
newNode.numKeys = M - d;
197+
198+
newNode.child[0] = p.child[d];
199+
for (i=1, j=d+1; j<=MAX; i++, j++)
200+
{
201+
newNode.key[i] = p.key[j];
202+
newNode.child[i] = p.child[j];
203+
}
204+
newNode.key[i] = lastKey;
205+
newNode.child[i] = lastChild;
206+
207+
p.numKeys = d - 1;
208+
209+
iKey.value = medianKey;
210+
iKeyRchild.value = newNode;
211+
}
212+
213+
public void Delete(int x)
214+
{
215+
if (root == null)
216+
{
217+
System.out.println("Tree is empty");
218+
return;
219+
}
220+
221+
Delete(x, root);
222+
223+
if (root != null && root.numKeys == 0) /*Height of the tree decreased by 1*/
224+
root = root.child[0];
225+
}
226+
227+
private void Delete(int x, Node p)
228+
{
229+
IntHolder n = new IntHolder(0);
230+
231+
if (SearchNode(x, p, n) == true) /* Key x found in node p */
232+
{
233+
if (p.child[n.value] == null) /* Node p is a leaf node */
234+
{
235+
DeleteByShift(p, n.value);
236+
return;
237+
}
238+
else /* Node p is a non-leaf node */
239+
{
240+
Node s = p.child[n.value];
241+
while (s.child[0] != null)
242+
s = s.child[0];
243+
p.key[n.value] = s.key[1];
244+
Delete(s.key[1], p.child[n.value]);
245+
}
246+
}
247+
else /* Key x not found in node p */
248+
{
249+
if (p.child[n.value] == null) /* p is a leaf node */
250+
{
251+
System.out.println("Value " + x + " not present in the tree");
252+
return;
253+
}
254+
else /* p is a non-leaf node */
255+
Delete(x, p.child[n.value]);
256+
}
257+
258+
if (p.child[n.value].numKeys < MIN)
259+
Restore(p, n.value);
260+
}
261+
262+
private void DeleteByShift(Node p, int n)
263+
{
264+
for (int i = n+1; i <= p.numKeys; i++)
265+
{
266+
p.key[i-1] = p.key[i];
267+
p.child[i-1] = p.child[i];
268+
}
269+
p.numKeys--;
270+
}
271+
272+
/* Called when p.child[n] becomes underflow */
273+
private void Restore(Node p, int n)
274+
{
275+
if (n != 0 && p.child[n-1].numKeys > MIN)
276+
BorrowLeft(p, n);
277+
else if (n != p.numKeys && p.child[n+1].numKeys > MIN)
278+
BorrowRight(p, n);
279+
else
280+
{
281+
if (n != 0) /*if there is a left sibling*/
282+
Combine(p, n); /*combine with left sibling*/
283+
else
284+
Combine(p, n+1); /*combine with right sibling*/
285+
}
286+
}
287+
288+
private void BorrowLeft(Node p, int n)
289+
{
290+
Node underflowNode = p.child[n];
291+
Node leftSibling = p.child[n-1];
292+
293+
underflowNode.numKeys++;
294+
295+
/*Shift all the keys and children in underflowNode one position right*/
296+
for (int i = underflowNode.numKeys; i > 0; i--)
297+
{
298+
underflowNode.key[i+1] = underflowNode.key[i];
299+
underflowNode.child[i+1] = underflowNode.child[i];
300+
}
301+
underflowNode.child[1] = underflowNode.child[0];
302+
303+
/* Move the separator key from parent node p to underflowNode */
304+
underflowNode.key[1] = p.key[n];
305+
306+
/* Move the rightmost key of node leftSibling to the parent node p */
307+
p.key[n] = leftSibling.key[leftSibling.numKeys];
308+
309+
/*Rightmost child of leftSibling becomes leftmost child of underflowNode */
310+
underflowNode.child[0] = leftSibling.child[leftSibling.numKeys];
311+
312+
leftSibling.numKeys--;
313+
}
314+
315+
private void BorrowRight(Node p, int n)
316+
{
317+
Node underflowNode = p.child[n];
318+
Node rightSibling = p.child[n+1];
319+
320+
/* Move the separator key from parent node p to underflowNode */
321+
underflowNode.numKeys++;
322+
underflowNode.key[underflowNode.numKeys] = p.key[n + 1];
323+
324+
/* Leftmost child of rightSibling becomes the rightmost child of underflowNode */
325+
underflowNode.child[underflowNode.numKeys] = rightSibling.child[0];
326+
327+
/* Move the leftmost key from rightSibling to parent node p */
328+
p.key[n + 1] = rightSibling.key[1];
329+
rightSibling.numKeys--;
330+
331+
/* Shift all the keys and children of rightSibling one position left */
332+
rightSibling.child[0] = rightSibling.child[1];
333+
for (int i = 1; i <= rightSibling.numKeys; i++)
334+
{
335+
rightSibling.key[i] = rightSibling.key[i+1];
336+
rightSibling.child[i] = rightSibling.child[i+1];
337+
}
338+
}
339+
340+
private void Combine(Node p, int m)
341+
{
342+
Node nodeA = p.child[m-1];
343+
Node nodeB = p.child[m];
344+
345+
nodeA.numKeys++;
346+
347+
/* Move the separator key from the parent node p to nodeA */
348+
nodeA.key[nodeA.numKeys] = p.key[m];
349+
350+
/* Shift the keys and children that are after separator key in node p
351+
one position left */
352+
int i;
353+
for (i = m; i < p.numKeys; i++)
354+
{
355+
p.key[i] = p.key[i+1];
356+
p.child[i] = p.child[i+1];
357+
}
358+
p.numKeys--;
359+
360+
/* Leftmost child of nodeB becomes rightmost child of nodeA */
361+
nodeA.child[nodeA.numKeys] = nodeB.child[0];
362+
363+
/* Insert all the keys and children of nodeB at the end of nodeA */
364+
for (i = 1; i <= nodeB.numKeys; i++)
365+
{
366+
nodeA.numKeys++;
367+
nodeA.key[nodeA.numKeys] = nodeB.key[i];
368+
nodeA.child[nodeA.numKeys] = nodeB.child[i];
369+
}
370+
}
371+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /