-
Notifications
You must be signed in to change notification settings - Fork 46
/
Copy pathbasicTemplate.cpp
157 lines (135 loc) · 4.19 KB
/
basicTemplate.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include <iostream>
#include "./NodeStructure.hpp"
using namespace std;
class BTree {
public:
int t;
BTreeNode *root;
BTree(int _t) {
root = NULL;
t = _t;
}
void Insert(int k);
void Traverse() {
if (root)
root->Traverse();
}
};
// Constructor of BTreeNode from "NodeStructure.hpp".
BTreeNode::BTreeNode(int _t, bool leaf) {
this->t = _t;
this->leaf = leaf;
this->keys = new int[(2 * t) - 1];
this->children = new BTreeNode *[2 * t];
this->n = 0;
}
// Driver function for Insertion of Data.
void BTree::Insert(int k) {
// If there is no Root.
if (root == NULL) {
root = new BTreeNode(t, true);
root->keys[0] = k;
root->n = 1;
return;
} else {
if (root->n == (2 * t) - 1) { // If the Root is Full.
BTreeNode *s = new BTreeNode(t, false); // Create a new Node as the root is full.
s->children[0] = root;
s->splitChild(0, root); // As we know, we have to split if the node is full.
int i = 0;
if (s->keys[0] < k)
i++;
s->children[1]->insertNonFull(k); // Insert Data.
root = s;
} else // If the Root is not full.
root->insertNonFull(k);
}
}
// Function which inserts data into node assuming that the space isn't full yet.
void BTreeNode::insertNonFull(int k) {
int i = n - 1;
// If the node is a Leaf Node.
if (leaf) {
// Get the position of the key to be inserted.
while (i >= 0 && keys[i] > k) {
keys[i + 1] = keys[i];
i--;
}
// Insert the key.
keys[i + 1] = k;
// Increment number of keys.
++n;
} else { // If the node is not a Leaf node.
while (i >= 0 && keys[i] > k) // Get the position of the node to be inserted.
i--;
// if the node is full.
if (children[i + 1]->n == (2 * t) - 1) {
// Split the node.
splitChild(i + 1, children[i + 1]);
// As we have to decide the bias whether it is left-median or right-median.
if (keys[i + 1] < k)
i++;
}
// insert k to the child's node.
children[i + 1]->insertNonFull(k);
}
return;
}
// Function for splitting a node.
void BTreeNode::splitChild(int i, BTreeNode *y) {
// As we're splitting a node into two, we need another node to accompany.
BTreeNode *z = new BTreeNode(y->t, y->leaf);
// Set number of keys for the new node equal to the degree.
z->n = t - 1;
// Copy the last t-1 nodes of 'y' to 'z'.
for (int j = 0; j < t - 1; j++)
z->keys[j] = y->keys[j + t];
// If Node 'y' isn't a leaf node.
if (!y->leaf) {
// Then, we must copy the node's children too.
for (int j = 0; j < t; j++)
z->children[j] = y->children[j + t];
}
// decrease the number of nodes in 'y'.
y->n = t - 1;
// Create space for new child (split node). Remember, this is the children of the node that called this function.
for (int j = n; j >= i + 1; j--)
children[j + 1] = children[j];
// Insert our new node into that space we've created.
children[i + 1] = z;
// Create space for the new key as the median of the children comes to it's parent.
for (int j = n - 1; j >= i; j--)
keys[j + 1] = keys[j];
// Insert the key into that position.
keys[i] = y->keys[t - 1];
// Increment the number of keys of this node (Root).
++n;
}
// Function for Traversing the Tree.
void BTreeNode::Traverse() {
int t;
// Traverse 'n' children.
for (t = 0; t < n; t++) {
// If the current node isn't a leaf, then we're sure that it has children. So, we call them first.
if (!leaf)
children[t]->Traverse();
// Print the key.
cout << keys[t] << " ";
}
// Subtree rooted with last child.
if (!leaf)
children[t]->Traverse();
}
int main() {
BTree *bt = new BTree(3);
bt->Insert(10);
bt->Insert(20);
bt->Insert(5);
bt->Insert(6);
bt->Insert(12);
bt->Insert(30);
bt->Insert(7);
bt->Insert(17);
bt->Traverse();
cout << endl;
}