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.
Input Specification:
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.
Output Specification:
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.
Sample Input 1:
6
7 8 9 10 7 4
结尾无空行
Sample Output 1:
Key 7 is duplicated
[9]
[4,7,8][9,10]
结尾无空行
Sample Input 2:
10
3 1 4 5 9 2 6 8 7 0
Sample Output 2:
[6]
[2,4][8]
[0,1][2,3][4,5][6,7][8,9]
Sample Input 3:
3
1 2 3
Sample Output 3:
[1,2,3]
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
#include <cmath>
#define ORDER 3
using namespace std;
class Node
{
public:
int cnt_data = 0; // 该节点所保存的数据量
int cnt_child = 0; // 子节点数
int data[ORDER + 1]; // 该节点所保存的具体数据(非叶子节点为索引,叶子节点为数据)
Node *child[ORDER + 2]; // 子节点
Node *parent = NULL; // 父节点,节点分裂时使用,根节点为NULL
Node *next; // 作为叶子节点时的相邻节点,实际上并没有用到这个
Node ()
{}
Node (Node *pra, int data_src[], pair<int, int> data_interval, Node *child_src[], pair<int, int> child_interval)
{
this->parent = pra;
this->cnt_data = data_interval.second - data_interval.first;
memcpy(this->data, data_src + data_interval.first, this->cnt_data * sizeof(data_src[0]));
this->cnt_child = child_interval.second - child_interval.first;
memcpy(this->child, child_src + child_interval.first, this->cnt_child * sizeof(child_src[0]));
for (int i = 0; i < cnt_child; ++i)
{
child[i]->parent = this;
}
}
void print ()
{
printf("[");
for (int i = 0; i < cnt_data; ++i)
{
if (i)
printf(",");
printf("%d", data[i]);
}
printf("]");
}
};
int n;
Node *Root = new Node();
int split_time = 0;
bool cmp (Node *p1, Node *p2)
{
return p1->data[0] < p2->data[0];
}
void print_tree ()
{
Node *BlankLine = NULL;
queue<Node *> que;
que.push(Root);
que.push(BlankLine);
while (!que.empty())
{
Node *t = que.front();
que.pop();
if (t == BlankLine)
{
printf("\n");
if (!que.empty())
que.push(BlankLine);
continue;
}
t->print();
for (int i = 0; i < t->cnt_child; ++i)
que.push(t->child[i]);
}
}
void split (Node *node)
{
int cntData = node->cnt_data;
int cntChild = node->cnt_child;
bool is_leaf = cntChild == 0;
Node **child = node->child;
int *data = node->data;
if ((is_leaf && cntData <= ORDER) ||(!is_leaf && cntData < ORDER))
return;
if (node->parent == NULL)
Root = node->parent = new Node();
Node *pra = node->parent;
int mid ;
Node *l ;
Node *r ;
if (is_leaf)
{
mid = ceil(1.0*ORDER/2);
l = new Node(pra, data, make_pair(0, mid), child, make_pair(0, 0));
r = new Node(pra, data, make_pair(mid, cntData), child, make_pair(0, 0));
}
else
{
mid = ceil(1.0*(ORDER-1)/2);
l = new Node(pra, data, make_pair(0, mid), child, make_pair(0, mid+1));
r = new Node(pra, data, make_pair(mid+1, cntData), child, make_pair(mid+1, cntChild));
}
pra->data[pra->cnt_data++] = data[mid];
if (pra->cnt_child > 0)
for (int i = 0; i < pra->cnt_child; ++i)
{
if (pra->child[i] == node)
{
pra->child[i] = l;
break;
}
}
else
pra->child[pra->cnt_child++] = l;
pra->child[pra->cnt_child++] = r;
sort(pra->data, pra->data + pra->cnt_data);
sort(pra->child, pra->child + pra->cnt_child, cmp);
delete node;
split(pra);
}
void insert (Node *node, int n)
{
if (node == NULL)
node = new Node();
node->data[node->cnt_data++] = n;
sort(node->data, node->data + node->cnt_data);
split(node);
}
Node *find (Node *root, int n)
{
if (root == NULL)
return root;
if (root->cnt_child == 0)
return root;
int i = upper_bound(root->data, root->data + root->cnt_data, n) - root->data;
return find(root->child[i], n);
}
bool exist (Node *node, int n)
{
if (node == NULL)
return false;
return binary_search(node->data, node->data + node->cnt_data, n);
}
int main ()
{
scanf("%d", &n);
for (int i = 0; i < n; ++i)
{
int num;
scanf("%d", &num);
Node *leaf = find(Root, num);
if (!exist(leaf, num))
insert(leaf, num);
else
printf("Key %d is duplicated\n", num);
}
print_tree();
return 0;
}