B-Tree
B-Tree
B-Tree
Creates an empty B-tree with a
single root node
● Allocate a new node (empty
root).
● Set the node as a leaf (x.leaf =
TRUE).
● Set the number of keys to zero
(x.n = 0).
● Write the node to disk.
●B-TREE-CREATE(T):
Assign the root to the tree.
1. x ← ALLOCATE-NODE()
2. x.leaf ← TRUE
3. x.n ← 0
4. DISK-WRITE(x)
5. T.root ← x
B-TREE-SPLIT-CHILD: Splitting a Node
Split a full node into two nodes B-TREE-SPLIT-CHILD(x, i):
1. z ← ALLOCATE-NODE()
and adjust the parent node to
2. y ← x.c[i]
maintain the B-tree properties. 3. z.leaf ← y.leaf
● Create a new node (z) to hold 4. z.n ← t - 1
the upper half of the keys 5. For j ← 1 to t - 1
from the full node (y). z.key[j] ← y.key[j + t]
● Move the median key from y 6. If not y.leaf
into the parent node (x). For j ← 1 to t
z.c[j] ← y.c[j + t]
● Update pointers and adjust
7. y.n ← t - 1
the size of the nodes (y and 8. Insert z as a new child
z). of x
● Write all modified nodes back 9. Write y, z, and x to disk
to disk.
B-TREE-INSERT: Adding a Key to a B-
Tree
Insert a new key into a B-tree while B-TREE-INSERT(T, k):
1. r ← T.root
maintaining the B-tree properties.
2. If r.n == 2t - 1:
• Check if the root is full: a. s ← ALLOCATE-NODE()
If full, split the root and create a b. T.root ← s
new root. c. s.leaf ← FALSE
The tree height increases by 1. d. s.n ← 0
e. s.c[1] ← r
● Recursively insert the key into f. B-TREE-SPLIT-
CHILD(s, 1)
the correct non-full child node.
g. B-TREE-INSERT-
● Use B-TREE-SPLIT-CHILD as NONFULL(s, k)
needed to ensure the recursion 3. Else:
descends into a non-full node. B-TREE-INSERT-
NONFULL(r, k)
B-TREE-INSERT-NONFULL: Recursive
Insertion into a Non-Full Node
B-TREE-INSERT-NONFULL(x, k):
Insert a key into a node that is not 1. i ← x.n
full, ensuring the B-tree properties 2. If x.leaf:
are maintained. a. While i ≥ 1 and k < x.key[i]:
x.key[i + 1] ← x.key[i]
i ← i - 1
● If the node is a leaf, insert the b. x.key[i + 1] ← k
key in the correct position. c. x.n ← x.n + 1
d. DISK-WRITE(x)
● If the node is an internal node: 3. Else:
Find the correct child for the key. a. While i ≥ 1 and k < x.key[i]:
If the child is full, split it using B- i ← i - 1
TREE-SPLIT-CHILD. b. i ← i + 1
Recursively insert the key into the c. If x.c[i].n == 2t - 1:
appropriate child. B-TREE-SPLIT-CHILD(x, i)
If k > x.key[i]:
i ← i + 1
d. B-TREE-INSERT-NONFULL(x.c[i], k)
B-TREE-DELETE: Removing Keys from a
B-Tree
B-TREE-DELETE(x, k):
Delete a key while maintaining B- 1. If k is in x and x.leaf:
tree properties. Remove k from x.
2. Else if k is in x (internal node):
a. If x.c[i] has ≥ t keys:
● If the key is in a leaf node, Replace k with predecessor.
remove it directly. Recursively delete
● If the key is in an internal node: predecessor.
Replace the key with its b. If x.c[i+1] has ≥ t keys:
Replace k with successor.
predecessor (from the left child) or Recursively delete successor.
successor (from the right child). c. Else:
● If a child node has fewer than t keys Merge x.c[i] and x.c[i+1].
during recursion: Recursively delete k in merged
Borrow a key from a sibling node.
(redistribution). 3. Else:
Merge nodes if borrowing isn’t possible. Descend to appropriate child node.
Ensure child node has ≥ t keys by
redistributing or merging.
Thanks!
Do you have any questions?