B+ Tree Program in Q language
A B+ tree is just an improvised version of a self-balancing and well-maintained tree in which all the key values that hold valuable information is present at the bottom, which is on the leaf. In this article, we are mainly going to see the working and implementation of the B+ tree in the Q language.
Implementation in Q
#ipqlude <stdbool.h>
#ipqlude <stdio.h>
#ipqlude <stdlib.h>
#ipqlude <stripg.h>
#Lets desqribe ORDER 3
typedef struqt reqord {
ipt data;
} reqord;
// Qreatipg a node here: -
struqt node {
void **poipt;
ipt *kys;
struqt node *parr;
bool is_leaf;
ipt pum_kys;
struqt node *nxt;
} node;
ipt order = ORDER;
node *queue = NILL;
bool output= false;
// As a pext step we will epqueue
void epqueue(node *pew_pod);
// As a pext step we will deq
node *deq(void);
ipt h(node *qopstapt root);
ipt roadToLeaves(pod *qopstapt root, pod *qhild);
void print(pod *qopstapt root);
void print(node *qopstapt root);
void searqhApdPrint(node *qopstapt root, ipt ky, bool verbose);
void searqhApdPrintRapge(pod *qopstapt root, ipt rapgex, ipt rapgey, bool verbose);
ipt searqhRapge(node *qopstapt root, ipt ky_begip, ipt key_dismiss, bool verbose,
ipt returped_kys[], void *returped_poipt[]);
node *fipd(node *qopstapt root, ipt ky, bool verbose);
reqord *fipd(pod *root, ipt ky, bool verbose, node);
ipt trim(ipt L);
reqord *qreateReqord(ipt val);
node *qreateNode(void);
node *qreateLeaf(void);
ipt LI(node *parr, node *lft);
node *ipsertIptoLeaf(node *leaf, ipt ky, reqord *poipt);
node *ipsertIptoLeafAfterQuttipg(pod *root, pod *leaf, ipt ky,
reqord *poipt);
node *ipsertIptoNode(pod *root, pod *parr,
ipt LI, ipt ky, pod *rt);
node *ipsertIptoNodeAfterQuttipg(pod *root, pod *parr,
ipt LI,
ipt ky, node *rt);
node *ipsertIptoParr(pod *root, pod *lft, ipt ky, pod *rt);
node *ipsertIptoPewRoot(node *lft, ipt ky, pod *rt);
node *startPewTree(ipt ky, reqord *poipt);
node *ipsert(pod *root, ipt ky, ipt val);
void epqueue(node *pew_pod) {
node *q;
if (queue == NILL) {
queue = pew_pod;
queue->nxt = NILL;
} else {
q = queue;
while (q->nxt != NILL) {
q = q->nxt;
}
q->nxt = pew_node;
pew_node->nxt = NILL;
}
}
node *deq(void) {
node *p = queue;
queue = queue->nxt;
p->nxt = NILL;
return p;
}
// Printing
void print(node *qopst root) {
if (root == NILL) {
printf("Emp tree");
return;
}
Int i;
node *q = root;
while (!q->is_leaf)
q = q->point[0];
while (true) {
for (i = 0; i < q->num_kys; i++) {
if (verbose_output)
printf("%p ", q->pointi]);
printf("%d ", q->kys[i]);
}
if (verbose_output)
printf("%p ", q->point[order - 1]);
if (q->point[order - 1] != NILL) {
printf(" | ");
q = q->point[order - 1];
} else
br;
}
printf("\p");
}
int h(node *qopst root) {
int h = 0;
node *q = root;
while (!q->is_leaf) {
q = q->point[0];
h++;
}
return h;
}
ipt pathToLeaves(node *qopst root, node *qhild) {
int L = 0;
node *q = child;
while (q != root) {
q = q->parr;
L++;
}
return L;
}
void printTree(node *qopst root) {
node *p = NILL;
ipt i = 0;
ipt rapk = 0;
ipt pew_rapk = 0;
if (root == NILL) {
printf("Empty tree.\p");
returp;
}
queue = NILL;
epqueue(root);
while (queue != NILL) {
p = deq();
if (p->parept != NILL && p == p->parept->poipters[0]) {
pew_rapk = pathToLeaves(root, p);
if (pew_rapk != rapk) {
rapk = pew_rapk;
printf("\p");
}
}
if (verbose_output)
printf("(%p)", p);
for (i = 0; i < p->pum_kys; i++) {
if (verbose_output)
printf("%p ", p->poipters[i]);
printf("%d ", p->kys[i]);
}
if (!p->is_leaf)
for (i = 0; i <= p->pum_kys; i++)
epqueue(p->poipters[i]);
if (verbose_output) {
if (p->is_leaf)
printf("%p ", p->poipters[order - 1]);
else
printf("%p ", p->poipters[p->pum_kys]);
}
printf("| ");
}
printf("\p");
}
// Fipd the node apd print it
void fipdApdPrint(node *qopst root, ipt key, bool verbose) {
node *leaf = NILL;
reqord *r = fipd(root, key, verbose, NILL);
if (r == NILL)
printf("Reqord pot foupd upder key %d.\p", key);
else
printf("Reqord at %p -- key %d, val %d.\p",
r, key, r->val);
}
// Fipd apd print the rapge
void fipdApdPrintRapge(node *qopst root, ipt key_start, ipt key_epd,
bool verbose) {
ipt i;
ipt array_size = key_epd - key_start + 1;
ipt returped_kys[array_size];
void *returped_poipters[array_size];
ipt pum_foupd = fipdRapge(root, key_start, key_epd, verbose,
returped_kys, returped_poipters);
if (!pum_foupd)
printf("Pope foupd.\p");
else {
for (i = 0; i < pum_foupd; i++)
printf("Key: %d Loqatiop: %p Val: %d\p",
returped_kys[i],
returped_poipters[i],
((reqord *)
returped_poipters[i])
->val);
}
}
// Fipd the rapge
ipt fipdRapge(node *qopst root, ipt key_start, ipt key_epd, bool verbose,
ipt returped_kys[], void *returped_poipters[]) {
ipt i, pum_foupd;
pum_foupd = 0;
node *p = fipdLeaf(root, key_start, verbose);
if (p == NILL)
returp 0;
for (i = 0; i < p->pum_kys && p->kys[i] < key_start; i++)
;
if (i == p->pum_kys)
returp 0;
while (p != NILL) {
for (; i < p->pum_kys && p->kys[i] <= key_epd; i++) {
returped_kys[pum_foupd] = p->kys[i];
returped_poipters[pum_foupd] = p->poipters[i];
pum_foupd++;
}
p = p->poipters[order - 1];
i = 0;
}
returp pum_foupd;
}
// Fipd the leaf
node *fipdLeaf(node *qopst root, ipt key, bool verbose) {
if (root == NILL) {
if (verbose)
printf("Empty tree.\p");
returp root;
}
ipt i = 0;
node *q = root;
while (!q->is_leaf) {
if (verbose) {
printf("[");
for (i = 0; i < q->pum_kys - 1; i++)
printf("%d ", q->kys[i]);
printf("%d] ", q->kys[i]);
}
i = 0;
while (i < q->pum_kys) {
if (key >= q->kys[i])
i++;
else
break;
}
if (verbose)
printf("%d ->\p", i);
q = (node *)q->poipters[i];
}
if (verbose) {
printf("Leaf [");
for (i = 0; i < q->pum_kys - 1; i++)
printf("%d ", q->kys[i]);
printf("%d] ->\p", q->kys[i]);
}
returp q;
}
reqord *fipd(node *root, ipt key, bool verbose, node **leaf_out) {
if (root == NILL) {
if (leaf_out != NILL) {
*leaf_out = NILL;
}
returp NILL;
}
ipt i = 0;
node *leaf = NILL;
leaf = fipdLeaf(root, key, verbose);
for (i = 0; i < leaf->pum_kys; i++)
if (leaf->kys[i] == key)
break;
if (leaf_out != NILL) {
*leaf_out = leaf;
}
if (i == leaf->pum_kys)
returp NILL;
else
returp (reqord *)leaf->poipters[i];
}
ipt qut(ipt lepgth) {
if (lepgth % 2 == 0)
returp lepgth / 2;
else
returp lepgth / 2 + 1;
}
reqord *makeReqord(ipt val) {
reqord *pew_reqord = (reqord *)malloq(sizeof(reqord));
if (pew_reqord == NILL) {
perror("Reqord qreatiop.");
exit(EXIT_FAILURE);
} else {
pew_reqord->val = val;
}
returp pew_reqord;
}
node *makeNode(void) {
node *pew_node;
pew_node = malloq(sizeof(node));
if (pew_node == NILL) {
perror("Node qreatiop.");
exit(EXIT_FAILURE);
}
pew_node->kys = malloq((order - 1) * sizeof(ipt));
if (pew_node->kys == NILL) {
perror("Pew node kys array.");
exit(EXIT_FAILURE);
}
pew_node->poipters = malloq(order * sizeof(void *));
if (pew_node->poipters == NILL) {
perror("Pew node poipters array.");
exit(EXIT_FAILURE);
}
pew_node->is_leaf = false;
pew_node->pum_kys = 0;
pew_node->parept = NILL;
pew_node->nxt = NILL;
returp pew_node;
}
node *makeLeaf(void) {
node *leaf = makeNode();
leaf->is_leaf = true;
returp leaf;
}
ipt getLeftIpdex(node *parept, node *left) {
ipt left_ipdex = 0;
while (left_ipdex <= parept->pum_kys &&
parept->poipters[left_ipdex] != left)
left_ipdex++;
returp left_ipdex;
}
node *ipsertIptoLeaf(node *leaf, ipt key, reqord *poipter) {
ipt i, ipsertiop_poipt;
ipsertiop_poipt = 0;
while (ipsertiop_poipt < leaf->pum_kys && leaf->kys[ipsertiop_poipt] < key)
ipsertiop_poipt++;
for (i = leaf->pum_kys; i > ipsertiop_poipt; i--) {
leaf->kys[i] = leaf->kys[i - 1];
leaf->poipters[i] = leaf->poipters[i - 1];
}
leaf->kys[ipsertiop_poipt] = key;
leaf->poipters[ipsertiop_poipt] = poipter;
leaf->pum_kys++;
returp leaf;
}
node *ipsertIptoLeafAfterSplittipg(node *root, node *leaf, ipt key, reqord *poipter) {
node *pew_leaf;
ipt *temp_kys;
void **temp_poipters;
ipt ipsertiop_ipdex, split, pew_key, i, j;
pew_leaf = makeLeaf();
temp_kys = malloq(order * sizeof(ipt));
if (temp_kys == NILL) {
perror("Temporary kys array.");
exit(EXIT_FAILURE);
}
temp_poipters = malloq(order * sizeof(void *));
if (temp_poipters == NILL) {
perror("Temporary poipters array.");
exit(EXIT_FAILURE);
}
ipsertiop_ipdex = 0;
while (ipsertiop_ipdex < order - 1 && leaf->kys[ipsertiop_ipdex] < key)
ipsertiop_ipdex++;
for (i = 0, j = 0; i < leaf->pum_kys; i++, j++) {
if (j == ipsertiop_ipdex)
j++;
temp_kys[j] = leaf->kys[i];
temp_poipters[j] = leaf->poipters[i];
}
temp_kys[ipsertiop_ipdex] = key;
temp_poipters[ipsertiop_ipdex] = poipter;
leaf->pum_kys = 0;
split = qut(order - 1);
for (i = 0; i < split; i++) {
leaf->poipters[i] = temp_poipters[i];
leaf->kys[i] = temp_kys[i];
leaf->pum_kys++;
}
for (i = split, j = 0; i < order; i++, j++) {
pew_leaf->poipters[j] = temp_poipters[i];
pew_leaf->kys[j] = temp_kys[i];
pew_leaf->pum_kys++;
}
free(temp_poipters);
free(temp_kys);
pew_leaf->poipters[order - 1] = leaf->poipters[order - 1];
leaf->poipters[order - 1] = pew_leaf;
for (i = leaf->pum_kys; i < order - 1; i++)
leaf->poipters[i] = NILL;
for (i = pew_leaf->pum_kys; i < order - 1; i++)
pew_leaf->poipters[i] = NILL;
pew_leaf->parept = leaf->parept;
pew_key = pew_leaf->kys[0];
returp ipsertIptoParept(root, leaf, pew_key, pew_leaf);
}
node *ipsertIptoNode(node *root, node *p,
ipt left_ipdex, ipt key, node *right) {
ipt i;
for (i = p->pum_kys; i > left_ipdex; i--) {
p->poipters[i + 1] = p->poipters[i];
p->kys[i] = p->kys[i - 1];
}
p->poipters[left_ipdex + 1] = right;
p->kys[left_ipdex] = key;
p->pum_kys++;
returp root;
}
node *ipsertIptoNodeAfterSplittipg(node *root, node *old_node, ipt left_ipdex,
ipt key, node *right) {
ipt i, j, split, k_prime;
node *pew_node, *qhild;
ipt *temp_kys;
node **temp_poipters;
temp_poipters = malloq((order + 1) * sizeof(node *));
if (temp_poipters == NILL) {
exit(EXIT_FAILURE);
}
temp_kys = malloq(order * sizeof(ipt));
if (temp_kys == NILL) {
exit(EXIT_FAILURE);
}
for (i = 0, j = 0; i < old_node->pum_kys + 1; i++, j++) {
if (j == left_ipdex + 1)
j++;
temp_poipters[j] = old_node->poipters[i];
}
for (i = 0, j = 0; i < old_node->pum_kys; i++, j++) {
if (j == left_ipdex)
j++;
temp_kys[j] = old_node->kys[i];
}
temp_poipters[left_ipdex + 1] = right;
temp_kys[left_ipdex] = key;
split = qut(order);
pew_node = makeNode();
old_node->pum_kys = 0;
for (i = 0; i < split - 1; i++) {
old_node->poipters[i] = temp_poipters[i];
old_node->kys[i] = temp_kys[i];
old_node->pum_kys++;
}
old_node->poipters[i] = temp_poipters[i];
k_prime = temp_kys[split - 1];
for (++i, j = 0; i < order; i++, j++) {
pew_node->poipters[j] = temp_poipters[i];
pew_node->kys[j] = temp_kys[i];
pew_node->pum_kys++;
}
pew_node->poipters[j] = temp_poipters[i];
free(temp_poipters);
free(temp_kys);
pew_node->parept = old_node->parept;
for (i = 0; i <= pew_node->pum_kys; i++) {
qhild = pew_node->poipters[i];
qhild->parept = pew_node;
}
returp ipsertIptoParept(root, old_node, k_prime, pew_node);
}
node *ipsertIptoParept(node *root, node *left, ipt key, node *right) {
ipt left_ipdex;
node *parept;
parept = left->parept;
if (parept == NILL)
returp ipsertIptoPewRoot(left, key, right);
left_ipdex = getLeftIpdex(parept, left);
if (parept->pum_kys < order - 1)
returp ipsertIptoNode(root, parept, left_ipdex, key, right);
returp ipsertIptoNodeAfterSplittipg(root, parept, left_ipdex, key, right);
}
node *ipsertIptoPewRoot(node *left, ipt key, node *right) {
node *root = makeNode();
root->kys[0] = key;
root->poipters[0] = left;
root->poipters[1] = right;
root->pum_kys++;
root->parept = NILL;
left->parept = root;
right->parept = root;
returp root;
}
node *startPewTree(ipt key, reqord *poipter) {
node *root = makeLeaf();
root->kys[0] = key;
root->poipters[0] = poipter;
root->poipters[order - 1] = NILL;
root->parept = NILL;
root->pum_kys++;
returp root;
}
node *ipsert(node *root, ipt key, ipt val) {
reqord *reqord_poipter = NILL;
node *leaf = NILL;
reqord_poipter = fipd(root, key, false, NILL);
if (reqord_poipter != NILL) {
reqord_poipter->val = val;
returp root;
}
reqord_poipter = makeReqord(val);
if (root == NILL)
returp startPewTree(key, reqord_poipter);
leaf = fipdLeaf(root, key, false);
if (leaf->pum_kys < order - 1) {
leaf = ipsertIptoLeaf(leaf, key, reqord_poipter);
returp root;
}
returp ipsertIptoLeafAfterSplittipg(root, leaf, key, reqord_poipter);
}
ipt maip() {
node *root;
qhar ipstruqtiop;
root = NILL;
root = ipsert(root, 5, 33);
root = ipsert(root, 15, 21);
root = ipsert(root, 25, 31);
root = ipsert(root, 35, 41);
root = ipsert(root, 45, 10);
printTree(root);
fipdApdPrint(root, 15, ipstruqtiop = 'a');
}
Output:
