2-3 Trees
2-3 Trees
In a 2-3 tree, insertion and deletion operations involve maintaining the structure of
the tree to ensure it remains balanced and retains its properties. The key properties
of a 2-3 tree are:
1. 2-Node: A node with one key and two children. The left child has values less than
the key, and the right child has values greater than the key.
2. 3-Node: A node with two keys and three children. The left child has values less
than the first key, the middle child has values between the first and second keys,
and the right child has values greater than the second key.
The tree is balanced, meaning that all paths from the root to any leaf have the same
length. This balance is maintained through split and merge operations during
insertions and deletions. The 2-3 tree guarantees a logarithmic height, providing
efficient search, insert, and delete operations with a time complexity of O(log n).
In summary, a 2-3 tree is a balanced search tree with nodes having either one key
and two children (2-node) or two keys and three children (3-node), ensuring
efficient operations and maintaining balance during updates.
Here's a high-level overview of the theory behind insertion and deletion operations
in a 2-3 tree:
Insertion Operation:
Deletion Operation:
Key Points:
During insertion and deletion, nodes are split or merged to maintain a balanced
structure.
Propagation of changes ensures that all ancestor nodes are updated to maintain the
properties of a 2-3 tree.
Rotations, borrowing keys, and merging nodes are common techniques to balance the
tree during insertions and deletions.
These operations guarantee that the 2-3 tree remains balanced and efficient for
search, insertion, and deletion, with a logarithmic height.
2-3 Program---
#include <stdio.h>
#include <stdlib.h>
struct Node {
int keys[2];
int keyCount;
};
newNode->keys[0] = key;
newNode->keyCount = 1;
newNode->child[i] = NULL;
return newNode;
}
// Function to insert a key into the 2-3 tree
if (root == NULL) {
return createNode(key);
} else {
if (root->keyCount == 2) {
temp->child[0] = root->child[1];
temp->child[1] = root->child[2];
root->child[1] = temp;
root->child[2] = NULL;
root->keys[1] = 0;
root->keyCount = 1;
return temp;
return root;
if (root != NULL) {
inOrderTraversal(root->child[0]);
inOrderTraversal(root->child[1]);
if (root->keyCount == 2) {
inOrderTraversal(root->child[2]);
freeTree(root->child[0]);
freeTree(root->child[1]);
freeTree(root->child[2]);
free(root);
root = root->child[0];
return root->keys[0];
if (root == NULL) {
return NULL;
} else {
root->keys[0] = 0;
root->keyCount = 0;
if (root->child[0] == NULL) {
free(root);
return NULL;
} else {
free(root);
return temp;
} else {
root->keys[0] = minKey;
if (root->child[1] == NULL) {
if (root->child[2]->keyCount == 2) {
root->child[1] = root->child[2]->child[0];
root->child[2]->child[0] = NULL;
root->keys[0] = root->child[2]->keys[0];
root->child[2]->keys[0] = root->child[2]->keys[1];
root->child[2]->keys[1] = 0;
root->child[2]->keyCount = 1;
} else if (root->child[0]->keyCount == 2) {
root->child[2] = root->child[1];
root->child[1] = root->child[0]->child[2];
root->child[0]->child[2] = NULL;
root->keys[0] = root->child[0]->keys[1];
root->child[0]->keys[1] = 0;
root->child[0]->keyCount = 1;
} else if (root->child[2]->keyCount == 1) {
root->child[2] = NULL;
root->keys[0] = root->child[0]->keys[1];
root->child[0]->keys[1] = 0;
root->child[0]->keyCount = 1;
return root;
int main() {
inOrderTraversal(root);
printf("\n");
inOrderTraversal(root);
printf("\n");
inOrderTraversal(root);
printf("\n");
inOrderTraversal(root);
printf("\n");
inOrderTraversal(root);
printf("\n");
inOrderTraversal(root);
printf("\n");
inOrderTraversal(root);
printf("\n");
// Delete a key from the 2-3 tree
inOrderTraversal(root);
printf("\n");
freeTree(root);
return 0;
Output====================================
This output demonstrates the 2-3 tree after each insertion and the tree after the
deletion of the key '7'. The in-order traversal of the tree is displayed at each step.