#include
#include
#include
#include
struct node {
bool isLeaf;
int size;
int key1;
int key2;
int key3;
node* first;
node* second;
node* third;
node* parent;
};
bool search(node* root, int key) {
if ((root->size >= 1 && key == root->key1) ||
(root->size >= 2 && key == root->key2) ||
(root->size == 3 && key == root->key3)) {
return true;
}
if (root->size >= 1 && key < root->key1 && !root->isLeaf) {
return search(root->first, key);
}
if (!root->isLeaf && root->size == 1 && key > root->key2) {
return search(root->second, key);
}
if (!root->isLeaf && root->size == 2 && key > root->key1 &&
key < root->key2) {
return search(root->second, key);
}
if (!root->isLeaf && root->size == 2 && key > root->key2) {
return search(root->third, key);
}
return false;
}
void update(node* root, node* child, int flag) {
if (root->size == 2) {
if (1 == flag) {
root->third = root->second;
root->second = root->first;
root->first = child;
} else if (2 == flag) {
root->third = root->second;
root->second = child;
}
} else if (root->size == 3) {
auto* tmp = new node;
tmp->isLeaf = root->isLeaf;
tmp->third = nullptr;
tmp->size = 1;
root->size = 1;
if (1 == flag) {
child->parent = tmp;
root->first->parent = tmp;
tmp->first = child;
tmp->second = root->first;
root->first = root->second;
root->second = root->third;
} else if (2 == flag) {
root->first->parent = tmp;
child->parent = tmp;
tmp->first = root->first;
tmp->second = child;
root->first = root->second;
root->second = root->third;
} else {
root->first->parent = tmp;
root->second->parent = tmp;
child->parent = root;
tmp->first = root->first;
tmp->second = root->second;
root->first = child;
root->second = root->third;
}
root->third = nullptr;
if (root->parent) {
int newFlag;
if (root->parent->first == root) {
newFlag = 1;
} else if (root->parent->second == root) {
newFlag = 2;
} else {
newFlag = 3;
}
root->parent->size += 1;
tmp->parent = root->parent;
update(root->parent, tmp, newFlag);
} else {
auto* p = new node;
p->isLeaf = false;
p->size = 1;
p->first = tmp;
p->second = root;
p->third = nullptr;
p->parent = nullptr;
tmp->parent = p;
root->parent = p;
}
}
}
void insert(node* root, int key) {
if (root->isLeaf) {
if (root->size == 0) {
root->key1 = key;
root->size = 1;
} else if (root->size == 1) {
root->size = 2;
if (key < root->key1) {
root->key2 = root->key1;
root->key1 = key;
} else if (key > root->key1) {
root->key2 = key;
}
} else if (root->size == 2) {
root->size = 3;
if (key < root->key1) {
root->key3 = root->key2;
root->key2 = root->key1;
root->key1 = key;
} else if (key > root->key1 && key < root->key2) {
root->key3 = root->key2;
root->key2 = key;
} else {
root->key3 = key;
}
} else if (root->size == 3) {
auto* tmp = new node;
tmp->first = nullptr;
tmp->second = nullptr;
tmp->third = nullptr;
tmp->size = 2;
tmp->isLeaf = true;
root->size = 2;
if (key < root->key1) {
tmp->key1 = key;
tmp->key2 = root->key1;
root->key1 = root->key2;
root->key2 = root->key3;
} else if (key > root->key1 && key < root->key2) {
tmp->key1 = root->key1;
tmp->key2 = key;
root->key1 = root->key2;
root->key2 = root->key3;
} else if (key > root->key2 && key < root->key3) {
tmp->key1 = root->key1;
tmp->key2 = root->key2;
root->key1 = key;
root->key2 = root->key3;
} else {
tmp->key1 = root->key1;
tmp->key2 = root->key2;
root->key1 = root->key3;
root->key2 = key;
}
if (root->parent) {
root->parent->size += 1;
int flag = 4;
if (root->parent->first == root) {
flag = 1;
} else if (root->parent->second == root) {
flag = 2;
} else if (root->parent->size >= 2 && root->parent->third == root) {
flag = 3;
}
tmp->parent = root->parent;
update(root->parent, tmp, flag);
} else {
auto* p = new node;
p->isLeaf = false;
p->size = 1;
p->first = tmp;
p->second = root;
p->third = nullptr;
p->parent = nullptr;
tmp->parent = p;
root->parent = p;
p->key1 = p->second->key1;
}
}
} else {
if (root->size == 1) {
if (key < root->key1) {
insert(root->first, key);
} else {
insert(root->second, key);
}
} else {
if (key < root->key1) {
insert(root->first, key);
} else if (key > root->key1 && key < root->key2) {
insert(root->second, key);
} else {
insert(root->third, key);
}
}
}
}
void updateKeys(node* root) {
node* curr;
if (!root->isLeaf) {
curr = root->second;
while (!curr->isLeaf) {
curr = curr->first;
}
root->key1 = curr->key1;
updateKeys(root->first);
updateKeys(root->second);
if (root->size == 2) {
curr = root->third;
while (!curr->isLeaf) {
curr = curr->first;
}
root->key2 = curr->key1;
updateKeys(root->third);
}
}
}
int main() {
int N, key, pivot;
std::cin >> N;
auto* root = new node;
root->isLeaf = true;
root->size = 0;
root->first = nullptr;
root->second = nullptr;
root->third = nullptr;
root->parent = nullptr;
for (int i = 0; i < N; ++i) {
std::cin >> key;
if (search(root, key)) {
printf("Key %d is duplicated\n", key);
} else {
insert(root, key);
while (root->parent) {
root = root->parent;
}
updateKeys(root);
}
}
std::vector vec;
vec.push_back(root);
pivot = 0;
std::set end;
end.insert(0);
while (pivot < vec.size()) {
if (!vec[pivot]->isLeaf) {
vec.push_back(vec[pivot]->first);
vec.push_back(vec[pivot]->second);
if (vec[pivot]->size == 2) {
vec.push_back(vec[pivot]->third);
}
if (end.find(pivot) != end.end()) {
end.insert(vec.size() - 1);
}
}
++pivot;
}
for (int i = 0; i < vec.size(); ++i) {
std::cout << "[" << vec[i]->key1;
if (vec[i]->size >= 2) {
std::cout << "," << vec[i]->key2;
}
if (vec[i]->size == 3) {
std::cout << "," << vec[i]->key3;
}
std::cout << "]";
if (end.find(i) != end.end() && i != vec.size() - 1) {
std::cout << std::endl;
}
}
return 0;
}
In this project, you are supposed to implement a B+ tree of order 3, with the following operations: initialize, insert (with splitting) and search. The B+ tree should be able to print out itself.
Each input file contains one test case. For each case, the first line contains a positive number N (≤104), the number of integer keys to be inserted. Then a line of the N positive integer keys follows. All the numbers in a line are separated by spaces.
For each test case, insert the keys into an initially empty B+ tree of order 3 according to the given order. Print in a line Key X is duplicated
where X
already exists when being inserted. After all the insertions, print out the B+ tree in a top-down lever-order format as shown by the samples.
6
7 8 9 10 7 4
Key 7 is duplicated
[9]
[4,7,8][9,10]
10
3 1 4 5 9 2 6 8 7 0
[6]
[2,4][8]
[0,1][2,3][4,5][6,7][8,9]
3
1 2 3
[1,2,3]