Data Structure Java - Collections Ok-466-482

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 17

Balanced Search Tree Data Structures 449

In a B-tree (as in any tree), a leaf node has no children.


We can also think of subtrees in a B-tree. Each non-leaf node in a 5-ary B-tree has up
to five subtrees. Each element in a non-leaf node has both a left subtree and a right
subtree.
Every B-tree is sorted. This means that the elements in any node and the elements in
that node's subtrees (if any) are arranged in ascending order. For example, consider B-
tree (a) in Figure 16.14. Its root node contains DK, IS, and NO, in that order. The left
subtree of DK contains elements (BE, CA, DE) that are less than DK. The right subtree of
DK / left subtree of IS contains elements (ES, FR, GR) that are greater than DK but less
than IS. The right subtree of IS / left subtree of NO contains elements that are greater than
IS but less than NO. The right subtree of NO contains elements that are greater than NO.
Because of the arrangement of elements in a B-tree, and because a B-tree is always
balanced, B-tree search, insertion, and deletion all have guaranteed O(log n) time
complexity, as we shall see.
We are now ready for a precise definition. A k-ary B-tree (or B-tree of order k) is a tree
with the following properties:
• The root node contains at least 1 and at most k — 1 elements. Every other node
contains at least (k — l)/2 and at most k — 1 elements.
• A non-leaf node that contains e elements (1 < e < k) also has links to exactly e + 1
child nodes. Each element sits between a pair of child links, which are links to its left
child and right child, respectively.
• All leaf nodes lie at the same depth. A leaf node has no children.
• The elements in each node are arranged in ascending order. For each element eletn in a
non-leaf node, all elements in elem's left subtree are less than elem, and all elements in
elem's right subtree are greater than elem.
The size of a B-tree is the total number of elements in that B-tree. The size of an
individual node is the number of elements in that node.
The empty B-tree has size zero. It has no nodes and no elements.
The arity of a B-tree is the maximum number of children per node, i.e., k:.
In Java, we can represent a B-tree by an object of class Btree, and each B-tree node
by an object of class Btree .Node, both classes being shown in Program 16.15. Figure
16.16 shows the detailed structures of Btree and Btree .Node objects.
This data structure is simple and clear, but rather wasteful of space. Every node
contains an array of child links, but in a leaf node these child links are all null. An
alternative would be to distinguish between leaf and non-leaf nodes, and let only a
non-leaf node contain an array of child links. (See Exercise 16.8.)

16.2.2 Search
B-tree search is quite straightforward. Figure 16.17 illustrates searches in a 5-ary B-tree:
(a) To search the B-tree for NO, we first look among the elements of the root node (DK,
IS, NO). We find NO there, so the search is successful.
(b) To search the B-tree for IT, we first look among the elements of the root node (DK, IS,
NO). We do not find IT there, but we see that IT is greater than IS and less than NO, so
450 lava Collections

we proceed to the right child of IS / left child of NO. Now we look among the
elements of that node (IT, LU, NL). We do find IT there, so the search is successful.
(c) To search the B-tree for DE, we first look among the elements of the root node (DK.
IS, NO). We do not find DE there, but we see that DE is less than DK, so we proceed
to the left child of DK. Now we look among the elements of that node (BE, CA. DE).
We do find DE there, so the search is successful.
(d) To search the B-tree for SE, we first look among the elements of the root node (DK.
IS, NO). We do not find SE there, but we see that SE is greater than NO. so we
proceed to the right child of NO. Now we look among the elements of that node (PT.
TR, UK, US). We do not find SE there, so we proceed to the left child of TR. But there
is no such child, so the search is unsuccessful.
These examples illustrate an advantage of a B-tree over a BST: the average search path
is shorter, since the B-tree is shallower. This advantage is, however, offset by the need to
search the elements within each B-tree node on the search path.
public class Btree {
/ / Each Btree object is a B-tree header.
/ / This B-tree is represented as follows: arity is the maximum number
/ / of children per node, and root is a link to its root node.
// Each B-tree node is represented as follows: size contains its size; a
// subarray elems[0. ..size-1] contains its elements;and a subarray
// childs[0...size] contains links to its child nodes. For each element
// elems[i], childs[i] is a link to its left child, and childs[i+l] is a
// link to its right child. In a leaf node, all child links are null.
/ / Moreover, for every element x in the left subtree of element y:
// x.compareTo(y) < 0
/ / and for every element z in the right subtree of element y:
// z.compareTo(y)> 0.
private int arity;
private Btree.Node root;
public Btree (int k) {
/ / Construct an empty B-tree of arity k.
root = null;
arity = k;

/ / Other Btree methods (see below).


111111111111 Inner class for B-tree nodes 111111111111
private static class Node {
/ / Each Btree. Node object is a B-tree node.
Program 16.15 Java class representing B-tree headers and nodes (continued on next page).
Balanced Search Tree Data Structures 451

private int size;


private Comparable[] elems;
private Node[] childs;
private Node (int k, Comparable elem,
Node left, Node right) {
/ / Construct a B-tree node of arity k, initially with one element, elem,
/ / and two children, left and right.
this.elems = new Comparable[k];
this.childs = new Node[k+1];
/ / ... Each array has one extra component, to allow for possible
/ / overflow.
this.size = 1;
this.elems[0] = elem;
this.chiIds[0] = left;
this.chiIds[1] = right;

private Node (int k, Comparable[] elems,


Node[] childs, int 1, int r) {
/ / Construct a B-tree node of arity k, with its elements taken from the
/ / subarray e 1 ems [ 1... r–1 ] and its children from the subarray
// childs[l...r].
this.elems = new Comparable[k];
this.childs = new Btree.Node[k+1];
this.size = 0;
for (int j = 1; j < r; j++) {
this.elems[this.size] = elems[j];
this.childs[this.size] = childs[j];
this.size++;

this.childs[this.size] = childs[r];

private boolean isLeaf () {


/ / Return true if and only of this node is a leaf.
return (childs[0] == null);

/ / Other Btree. Node methods (see below).


}
}

Program 16.15 (continued)


452 Java Collections

class tag arity root


I Btree | k \ «y

root node

class tag size 0 e-l k-\


|Btree.Node| e u V II Z it elems

f t // T 1 // 1 childs
left right child right child right
child of / left of yl left child
of u child of v child of z of z

Figure 16.16 Detailed structures of Btree and Btree .Node objects representing a k-ary B-tree.

(a) Searching for NO: j»-|- j. Key:


search path

(b) Searching for IT:

(c) Searching for DE:

(d) Searching for SE:

unsuccessful
Figure 16.17 Illustrations of search in a 5-ary B-tree.
Balanced Search Tree Data Structures 453

To find which if any node of a B-tree contains an element equal to target:

1. If the B-tree is empty, terminate with answer none.


2. Set curr to the B-tree's root node.
3. Repeat:
3.1. Search for elem in node curr.
3.2. If elem was found in node curr, terminate with answer curr.
3.3. If elem was not found in node curr:
3.3.1. If curr is a leaf node, terminate with answer none.
3.3.2. If curr is a non-leaf node:
3.3.2.1. Set curr to the left child of the least element in node
curr greater than elem (or equivalently the right
child of the greatest element less than elem).

Algorithm 16.18 B-tree search algorithm.

public Btree.Node search (Comparable target) {


// Find which if any node of this B-tree contains an element equal to target.
// Return a link to that node, or null if there is no such node.
if (root == null)
return null;
Btree.Node curr = root;
for ( ; ; ) {
int pos = curr . searchInNode( target );
if (target .equals (curr .elems [pos] ) )
return curr;
else if (curr . isLeaf ( ) )
return null;
else
// Continue the search in childs [ currPos ] , which is the left
// child of the least element in node curr greater than target.
curr = curr . childs [pos] ;

//////////// In inner class Btree . Node . . . ////////////


private int searchlnNode (Comparable target) {
// Return the index of the least element in this node that is not less than
// target.
// See code on the companion Web site.

Program 16.19 Implementation of the B-tree search algorithm as a Java method (in class Btree),
with an auxiliary method (in class Btree .Node).
454 lava Collections

Algorithm 16.18 captures the idea of B-tree search. It can be seen as a generalization of
BST search (Algorithm 10. 10).
Program 16.19 shows an implementation of the B-tree search algorithm. The search
method belongs to the Btree class (Program 16.15). The auxiliary searchlnNode
method belongs to the Btree.Node inner class. It searches a node for the target
element, using the array binary search algorithm. (Binary search might seem excessive
for a 5-ary B-tree, whose nodes contain at most 4 elements, but it is fully justified in
practical applications where we use high-arity B-trees.)

(a) After inserting {_•-


US:

(b) After inserting


CA, UK, FR:

(c) After inserting [•-

A
IS:

•CA»FR» •UK»US»

(d) After inserting


DK, NO, NL,
IS
BE:

[•BE»CA»DK»FR«

(e) After inserting


LU:

•BE»CA»DK»FR»| j•LU^NL*] [•UK*US*|

(f) After inserting [•


PT:

|*PT*UK»US»|

Figure 16.20 Illustration of insertions in an (initially empty) 5-ary B-tree (continued on next page}.
Balanced Search Tree Data Structures 455

(g) After inserting


GR:

(h) After inserting {•


TR, IT, DE,
ES:

(i) After inserting •


HU, CZ:

(k) After inserting [•


IE:

Figure 16.20 (continued)


456 Java Collections

16.2.3 Insertion
Now let us consider the problem of inserting a new element into a B-tree. We start with a
complete illustration.

EXAMPLE 16.1 B-tree insertions

Figure 16.20 illustrates the effects of successfully inserting country-codes into a 5-ary B-
tree. Initially, the B-tree is empty, i.e., its header contains a null link. Let us study this
illustration in detail.
(a) To insert US into the B-tree, we create a root node containing only US. (This root
node is also a leaf node.)
(b) To insert CA, UK, and FR into the B-tree, we insert these elements in the root node,
keeping it sorted.
(c) To insert IS into the B-tree, we first attempt to insert it in the root node. But this makes
the node overflow, since it now contains too many elements (CA, FR, IS, UK, US).
(See below left, where the overflowed node is highlighted.) So we identify the median
of these five elements (IS), and split the leaf node into a pair of siblings: one contain-
ing the elements less than the median (CA, FR) and one containing the greater
elements (UK, US). We move the median itself up to the parent node. Since in
this case there is no parent node (we are splitting the root node), we must create a
new parent node and move the median up to it. (See below right.)

lesser median greater


elements elements

(d) To insert DK into the B-tree, we first look among the elements of the root node. Since
DK is less than IS, we proceed to the first child node. Since the latter is a leaf node, we
insert DK in it. Similarly, to insert NO, NL, and BE into the B-tree. we insert them in
the second, second, and first child nodes, respectively.
(e) To insert LU into the B-tree, we first look among the elements of the root node. Since
LU is greater than IS, we proceed to the second child node. Since the latter is a leaf
node, we attempt to insert LU in it. But this makes the leaf node overflow. (See below
left.) So we identify the median element (NO), and split the leaf node into a pair of
siblings: one containing the lesser elements (LU, NL) and one containing the greater
elements (UK, US). We move the median itself up to the parent node, which now
contains two elements (IS, NO). (See below right.)
Balanced Search Tree Data Structures 457

lesser median greater


elements elements

(f) To insert PT into the B-tree, we straightforwardly insert it in the third child node.
(g) To insert GR into the B-tree, we attempt to insert it in the first child node. But this
makes the node overflow. So we split it into a pair of siblings, one containing BE and
CA, the other containing FR and GR, and we move the median DK up to the parent
node.
(h) To insert TR, IT, DE, and ES into the B-tree, we straightforwardly insert them in the
fourth, third, first, and third child nodes, respectively,
(i) To insert HU and CZ into the B-tree, we straightforwardly insert them in the second
and first child nodes, respectively,
(j) To insert PL into the B-tree, we attempt to insert it in the fourth child node. But this
makes the node overflow. So we split it into a pair of siblings, one containing PL and
PT, the other containing UK and US, and we move the median TR up to the parent
node,
(k) To insert IE into the B-tree, we attempt to insert it in the second child node. But this
makes the node overflow:

So we split this node into a pair of siblings, one containing ES and FR, the other contain-
ing HU and IE, and we move the median GR up to the parent node. But this makes the
parent node itself overflow:
458 lava Collections

So we split the parent node likewise into a pair of siblings, one containing DK and GR.
the other containing NO and TR, and we move the median IS up to a newly-created
grandparent node, which we make the root node:

The ideas illustrated in Example 16.1 are captured by Algorithms 16.21 and 16.22. The
main algorithm searches the tree in much the same way as the B-tree search algorithm.
When the algorithm reaches a leaf node, it inserts the new element in that leaf node (step
4). If that leaf node has overflowed (i.e., it now has k elements), the auxiliary algorithm is
called to split that node (step 5).
The auxiliary algorithm splits a given node. It first determines the median of that
node's elements (step 1). Then it splits node curr into two siblings: left-sib takes the
elements less than the median, with their children (step 2); and right-sib takes the
elements greater than the median, with their children (step 3). Finally, the algorithm
moves the median itself, and its children left-sib and right-sib, up to the parent node. If
there is no parent node, the algorithm creates one (step 4.1). If a parent node already
exists, the algorithm inserts the median into the parent node (step 5.1). and then if
necessary it splits the parent node by a recursive call to itself (step 5.2).
Program 16.23 shows a Java implementation of B-tree insertion. The insert and
splitNode methods belong to the Btree class. They closely follow Algorithms 16.21
and 16.22, respectively, with one important extra detail. Whenever insert moves
down the tree from parent to child, it stacks the parent node. Thereafter, if splitNode
has to move an element up from child to parent, it finds the parent node at the top of the
stack. Moreover, since insert has already searched the parent node in order to decide
which child link to follow, it also stacks the child link's position, for that is exactly where
splitNode must insert any element moved up from child to parent.
The second auxiliary method, insertlnNode, belongs to the Btree .Node inner
class. It inserts a given element, with its children, at a given position in the node.
Note that splitNode creates two new nodes, l e f t Sib and right Sib. and
discards the node that is being split. This makes the code elegant and readable. However,
it would be more efficient to create only one new node, and reuse the node that is being
split. (See Exercise 16.10.)
459

To insert element elem into a B-tree:


1. If the B-tree is empty:
1.1, Make the B-tree's root a newly-created leaf node containing one
element, elem.
1.2. Terminate.
2. Set curr to the B-tree's root node.
3. Repeat:
3.1. Search for elem in node curr.
3.2. If elem was found in node curr:
3.2.1. Terminate.
3.3. If elem was not found in node curr:
3.3.1. If curr is a leaf node, exit the loop.
3.3.2. If curr is a non-leaf node:
3.3.2.1. Set curr to the left child of the least element in node
curr greater than elem (or equivalently the right child
of the greatest element less than elem).
4. Insert elem into leaf node curr, keeping its elements sorted.
5. If node curr has overflowed, split node curr.
6. Terminate,
Algorithm 16.21 B-tree insertion algorithm.

To split an overflowed node, node, in a B-tree:


1. Let med be the median of node's elements.
2. Make left-sib a newly-created node, containing all of node's elements to the
left of med, with all their children.
3. Make right-sib a newly-created node, containing all of node's elements to the
right of med, with all their children.
4. If node is the B-tree's root node:
4.1. Make the B-tree's root a newly-created node containing one element,
med, with children left-sib and right-sib.
5. If node has a parent node:
5.1. Insert med, with children left-sib and right-sib, into node's parent,
keeping its elements sorted.
5.2. If node's parent has overflowed, split the parent node.
6. Terminate.
Algorithm 16.22 B-tree insertion: auxiliary algorithm to split an overflowed node.
460 lava Collections

public void insert (Comparable elem) {


/ / Insert element elem into this B-tree.
if (root == null) {
root = new Btree.Node (arity, elem, null, null);
return ;
}
Stack ancestors = new LinkedStack( ) ;
Btree.Node curr = root;
for ( ; ; ) {
int currPos = curr . searchlnNode (elem) ;
if (elem. equals (curr . elems [currPos] ) )
return ;
else if (curr .isLeaf ( ) )
break;
else {
/ / Continue the search in childs [ currPos ] , which is the left
/ / child of the least element in node curr greater than elem.
ancestors . addLast (new Integer (currPos ) ) ;
ancestors .addLast (curr) ;
curr = curr .childs [currPos] ;

curr . insertInNode( elem, null, null, currPos);


if (curr. size == arity) // curr has overflowed
splitNode (curr , ancestors);

Program 16.23 Implementation of the B-tree insertion algorithm as a Java method, with auxiliary
methods (in class Btree) (continued on next page).

16.2.4 Deletion
Now let us consider the problem of deleting an element from a B-tree. We start with a
complete illustration.

EXAMPLE 16.2 B-tree deletions


Figure 16.24 illustrates the effects of successfully deleting country -codes from a 5-ary B-
tree. Let us study this illustration in detail.
(a) To delete GR from the B-tree, we first search for it and find it in a leaf node. We
simply delete GR from that leaf node.
(b) To delete IS from the B-tree, we first search for it and find it in a non-leaf node. We
take the least element in IS's right subtree, namely IT. and move it up to replace IS in
the non-leaf node.
(c) To delete ES from the B-tree, we first search for it and find it in a leaf node. We delete
ES from the leaf node. But this causes the leaf node to underflow, containing fewer
Balanced Search Tree Data Structures 461

private void splitNode (Btree.Node node,


Stack ancestors) {
/ / Split the overflowed node in this B-tree. The stack ancestors contains
/ / all ancestors of node, together with the known insertion position in each of
/ / these ancestors.
int medPos = node. size/ 2;
Comparable med = node.elems [medPos] ;
Btree.Node leftSib = new Btree .Node (arity,
node.elems, node.childs, 0, medPos);
Btree.Node rightSib = new Btree.Node (arity,
node.elems, node.childs, medPos+1, node. size);
if (node == root)
root = new Btree.Node (arity, med, leftSib,
rightSib) ;
else {
Btree.Node parent =
(Btree.Node) ancestors .removeLast () ;
int parentlns = ( (Integer)
ancestors . removeLast ( ) ) . intValue ( ) ;
parent . insertlnNode (med, leftSib, rightSib,
parentlns) ;
if (parent, size == arity) // parent has overflowed
splitNode (parent , ancestors);

/ / / / / / / / / / / / I n inner class Btree . Node ... / / / / / / / / / / / /


private void insertlnNode (Comparable elem,
Btree.Node leftChild,
Btree.Node rightChild,
int ins) {
/ / Insert element elem, with children leftChild and rightChild, at
/ / position ins in this node.
for (int i = node. size; i > ins; i--) {
elems[i] = elems[i-l];
childs[i+l] = c h i l d s t i ] ;
}
size++ ;
elems[ins] = elem;
childs[ins] = leftChild;
childs [ins+1] = rightChild;

Program 16.23 (continued)


462 lava Collections

than 2 elements. (See below left, where the underflowed node is highlighted.) So we
must try to restock the underflowed node by moving an element from one of its
nearest siblings. The right sibling cannot lose any elements without itself underflow-
ing. Fortunately, the left sibling contains more than enough elements. So we move the
left sibling's righmost element DE up to the parent node, replacing DK, and move DK
itself down to the underflowed node:

(d) To delete DK from the B-tree, we first search for it and find it in a leaf node. We
delete DK from the leaf node. But this causes the leaf node to underflow. Moreover,
we cannot restock the leaf node by moving an element from either of its left or right
siblings, without making that sibling underflow. However, we can coalesce the
underflowed node with either of its siblings. Suppose that we choose to coalesce it
with its right sibling. We move all that sibling's elements (LU, NL) into the under-
flowed node, together with the intermediate element from the parent node (IT):

Deleting an element in a leaf node is easy. Deleting an element in a non-leaf node


needs a little more work: we must replace it by the least element in its right subtree. The
latter element is always in a leaf node.
Every deletion therefore causes some leaf node (not necessarily the node containing
the element to be deleted) to contract. If that node underflows, it must be restocked.
Restocking an underflowed node always involves that node's nearest sibling (or one of
its nearest siblings, if it has two). Restocking is straightforward if a nearest sibling has at
least one spare element, which it can give up without underflowing.
Restocking is less straightforward if neither sibling has spare elements. But in these
circumstances it is always possible to coalesce the underflowed node with one of its
nearest siblings. The sibling must contain (k — l)/2 elements (the minimum), and the
underflowed node (k — l)/2 — 1 elements (one less than the minimum). In total they
contain at most k — 2 elements. That leaves at least one spare slot for the intermediate
element to be moved down from the parent node to the coalesced node.
Balanced Search Tree Data Structures 463

(If k is odd, the underflowed node and its sibling together contain exactly k - 2
elements. If k is even, they actually contain k - 3 elements, since in (k - l)/2 we discard
the remainder.)
All these ideas are captured by Algorithms 16.25 and 16.26. The main algorithm
should be easy to understand. The auxiliary algorithm, which restocks an underflowed
node, breaks down into three cases. Step 1 deals with the case of an underflowed root
node, which contains no elements at all, and so can simply be discarded. Step 2 deals with
the case of an underflowed node that has a nearest sibling with a spare element. Step 3
Initially:

•BE»CA*DE»

(a) After deleting !•-


GR:

•BE*CA*DE» |»IT»LU»NL»|

(b) After deleting


IS:

•ES»FR»||•LU^NL*||•PT«TR»UK»US«|

(c) After deleting [•


ES:

(d) After deleting »


DK:

Figure 16.24 Illustration of deletions in a 5-ary B-tree.


464 lava Collections

To delete the element elem from a B-tree:


1. Find which if any node curr of the B-tree contains an element equal to elem.
2. If there is no such node, terminate.
3. If curr is a leaf node:
3.1. Remove elem from node curr.
3.2. If node curr has underflowed, restock curr.
4. If curr is not a leaf node:
4.1. Let leftmost-node be the leftmost leaf node in the right subtree of elem.
4.2. Let next-elem be the leftmost element in leftmost-node, and remove
next-elem from leftmost-node.
4.3. Replace elem in node curr by next-elem.
4.4. If leftmost-node has underflowed, restock leftmost-node.
5. Terminate.
Algorithm 16.25 B-tree deletion algorithm.

To restock an underflowed node, node, in a B-tree:


1. If node is the root of the B-tree (and so has 0 elements and 1 child):
1.1. Replace the root of the B-tree by node's only child.
1.2. Terminate.
2. If node has a nearest left (or right) sibling with more than the minimum
number of elements:
2.1. Let sib be that nearest sibling.
2.2. Let parent-elem be the element in node's parent whose children are
node and sib.
2.3. Let spare-elem and spare-child be the rightmost (leftmost) element and
child in sib, and remove them from sib.
2.4. Insert parent-elem and spare-child as the leftmost (rightmost) element
and child of node.
2.5. Replace parent-elem by spare-elem in node's parent.
3. If node has no nearest sibling with more than the minimum number of
elements:
3.1. Let sib be the left (or right) nearest sibling of node.
3.2. Lei parent-elem be the element in node's parent whose children are
node and sib.
3.3. Insert all sib's elements and children, followed (preceded) by parent-
elem, as the leftmost (rightmost) elements and children of node.
3.4. Remove parent-elem and the child sib from node's parent.
3.5. If node's parent has underflowed, restock node's parent.
4. Terminate.
Algorithm 16.26 B-tree deletion: auxiliary algorithm to restock an underflowed node.
Balanced Search Tree Data Structures 465

deals with the case of an underflowed node that must be coalesced with a nearest sibling,
In the last case the parent node contracts and might itself underflow; if that happens, the
algorithm calls itself recursively to restock the parent node.
We leave the implementation of B-tree deletion to Exercise 16. 1 1 .

1 6.2.5 Analysis
Search
Lei us analyze the B-tree search algorithm.
First consider searching a full k-ary B-tree, i.e., one in which every node has size k — 1 .
From equation (16.6), this B-tree has size n — kd+l — 1 . Conversely, if we know n, we
can determine the B-tree' s depth:
d = \ogk(n + 1) - 1
Algorithm 16.18 starts by visiting the root node, and each subsequent iteration visits a
child of the current node. We can immediately deduce that:
Maximum no. of nodes visited = d + 1

= log2(n + l)/log 2 k (16.7)


(See Section B.2 for an explanation of the mathematics used here.) Assuming binary
search of the k — 1 elements in each visited node, the number of comparisons at each
node is about Iog2(k — 1). Therefore:
Maximum no. of comparisons ~ Iog2(k — l)logk.(n + l)/log 2 k
~ Iog2n (16.8)
Now consider searching a half-full k-ary B-tree, i.e., one in which every node has size
(k — 1)12. Such a B-tree is similar to a full B-tree of order (k + l)/2. On reworking the
above analysis we obtain:
Maximum no. of nodes visited = Iog2(n + l)/log2((k + l)/2)
= log2(n + 1 )/(log2(k + 1 ) - 1 ) ( 1 6.9)

Maximum no. of comparisons ~ Iog2n (16.10)


Both these analyses lead to the same conclusion: the time complexity of B-tree search
is O(log n). The actual maximum number of comparisons for searching a B-tree is about
the same as for searching a balanced BST. Remarkably, the maximum number of
comparisons depends neither on the B-tree' s arity nor on how full it is. Thus B-tree
search is guaranteed to be as fast as searching a balanced BST.

Insertion
The B-tree insertion algorithm, by the same reasoning, needs about Iog2n comparisons to
find the node where the new element will be inserted. There is the added complication of

You might also like