Skip to content
Snippets Groups Projects
Commit d7a28fbb authored by Alec's avatar Alec
Browse files

split root now soft

parent 3fc3d0df
Branches
No related tags found
No related merge requests found
#include "bp_tree.h" #include "bp_tree.h"
#include <math.h>
#include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h>
#include <math.h>
typedef struct control { typedef struct control {
int value; int value;
...@@ -10,14 +10,9 @@ typedef struct control{ ...@@ -10,14 +10,9 @@ typedef struct control{
node *rhs; node *rhs;
} control; } control;
const control CONST_CONTR = { const control CONST_CONTR = {.value = 0, .lhs = NULL, .rhs = NULL};
.value = 0,
.lhs = NULL,
.rhs = NULL
};
node* bp_create_node() node *bp_create_node() {
{
node *nd = malloc(sizeof(node)); node *nd = malloc(sizeof(node));
for (int i = 0; i < M + 1; i++) for (int i = 0; i < M + 1; i++)
...@@ -29,8 +24,7 @@ node* bp_create_node() ...@@ -29,8 +24,7 @@ node* bp_create_node()
return nd; return nd;
} }
control value_to_insert(int val) control value_to_insert(int val) {
{
control c; control c;
c.value = val; c.value = val;
c.lhs = c.rhs = NULL; c.lhs = c.rhs = NULL;
...@@ -39,25 +33,24 @@ control value_to_insert(int val) ...@@ -39,25 +33,24 @@ control value_to_insert(int val)
bool bp_is_leaf(node *nd) { return nd->childs[0] == NULL; } bool bp_is_leaf(node *nd) { return nd->childs[0] == NULL; }
void bp_node_shift(node *nd, int index) void bp_node_shift(node *nd, int index) {
{ // as there is one more child than values, we must do one more iteration
// as there is one more child than values, we must do one more iteration outside of the for // outside of the for
nd->childs[M] = nd->childs[M - 1]; nd->childs[M] = nd->childs[M - 1];
for (int i = M-1; i > index; i--) for (int i = M - 1; i > index; i--) {
{
nd->data[i] = nd->data[i - 1]; nd->data[i] = nd->data[i - 1];
nd->childs[i + 1] = nd->childs[i]; nd->childs[i + 1] = nd->childs[i];
} }
} }
node* bp_split(node *nd) node *bp_split(node *nd) {
{
node *new = bp_create_node(); node *new = bp_create_node();
/* /*
this weird thing is for the for loop this weird thing is for the for loop
up to how many loop do we want to do up to how many loop do we want to do
we need it outside because if the order of the tree is odd, we must do one more loop we need it outside because if the order of the tree is odd, we must do
one more loop
*/ */
int upto = (int)floor(M / 2); int upto = (int)floor(M / 2);
int index = upto; int index = upto;
...@@ -67,14 +60,12 @@ node* bp_split(node *nd) ...@@ -67,14 +60,12 @@ node* bp_split(node *nd)
new->count = upto; new->count = upto;
// as explained, do shit if the order is odd // as explained, do shit if the order is odd
if (M%2 == 1) if (M % 2 == 1) {
{
upto++; upto++;
new->count++; new->count++;
} }
for (int i = 0; i < upto; i++) for (int i = 0; i < upto; i++) {
{
new->data[i] = nd->data[index + i]; new->data[i] = nd->data[index + i];
nd->data[index + i] = 0; nd->data[index + i] = 0;
new->childs[i] = nd->childs[index + i]; new->childs[i] = nd->childs[index + i];
...@@ -84,22 +75,20 @@ node* bp_split(node *nd) ...@@ -84,22 +75,20 @@ node* bp_split(node *nd)
return new; return new;
} }
control bp_insert_into(node *nd, control val) control bp_insert_into(node *nd, control val) {
{ // look for a 0 in the node (it is guarenteed to exist in this version of
// look for a 0 in the node (it is guarenteed to exist in this version of the algorithm) // the algorithm)
for (int i = 0; i < M; i++) for (int i = 0; i < M; i++) {
{
// if we plainly find a 0 // if we plainly find a 0
if (nd->data[i] == 0) if (nd->data[i] == 0) {
{
nd->data[i] = val.value; nd->data[i] = val.value;
nd->childs[i] = val.lhs; nd->childs[i] = val.lhs;
break; break;
} }
// if we need to insert the value between two values, we need to shifter everything greater than our value one case further // if we need to insert the value between two values, we need to
if (nd->data[i] > val.value) // shifter everything greater than our value one case further
{ if (nd->data[i] > val.value) {
bp_node_shift(nd, i); bp_node_shift(nd, i);
nd->data[i] = val.value; nd->data[i] = val.value;
nd->childs[i] = val.rhs; nd->childs[i] = val.rhs;
...@@ -109,15 +98,15 @@ control bp_insert_into(node *nd, control val) ...@@ -109,15 +98,15 @@ control bp_insert_into(node *nd, control val)
nd->count++; nd->count++;
// if the node is now full, we split // if the node is now full, we split
if (nd->count == M) if (nd->count == M) {
{
control v; control v;
node *new = bp_split(nd); node *new = bp_split(nd);
v.lhs = nd; v.lhs = nd;
v.rhs = new; v.rhs = new;
v.value = new->data[0]; v.value = new->data[0];
// if the new node we created is a leaf, we must add it to the linked list // if the new node we created is a leaf, we must add it to the
// linked list
if (bp_is_leaf(new)) if (bp_is_leaf(new))
nd->next = new; nd->next = new;
...@@ -127,80 +116,85 @@ control bp_insert_into(node *nd, control val) ...@@ -127,80 +116,85 @@ control bp_insert_into(node *nd, control val)
} }
control bp_insert(node *nd, control val) { control bp_insert(node *nd, control val) {
control c; // will help us to return the pivot, and the two pointers of the childs-to-be control c; // will help us to return the pivot, and the two pointers of the
// childs-to-be
// if we are in a leaf, we found where to insert the value, so let's do it // if we are in a leaf, we found where to insert the value, so let's do it
if (bp_is_leaf(nd)) if (bp_is_leaf(nd))
c = bp_insert_into(nd, val); c = bp_insert_into(nd, val);
else // otherwise let's keep looking else // otherwise let's keep looking
{ {
for (int i = 0; i < M; i++) for (int i = 0; i < M; i++) {
{ if (nd->data[i] > val.value || nd->data[i] == 0) {
if (nd->data[i] > val.value || nd->data[i] == 0)
{
c = bp_insert(nd->childs[i], val); c = bp_insert(nd->childs[i], val);
break; break;
} }
} }
} }
// if a split happened // if a split happened
if (c.value != 0) if (c.value != 0) {
{
return c; return c;
} }
return CONST_CONTR; return CONST_CONTR;
} }
node* bp_split_root(node *root) node *bp_split_root(node *root) {
{
// TEMPORARY FUNC (COPYRIGHT), HARD WRITTEN NEEDS TO BE SOFT // TEMPORARY FUNC (COPYRIGHT), HARD WRITTEN NEEDS TO BE SOFT
node *new = bp_create_node(); node *new = bp_create_node();
node *rhs = bp_create_node(); node *rhs = bp_create_node();
rhs->childs[0] = root->childs[3]; int index = (int)floor(M / 2);
rhs->childs[1] = root->childs[4];
int looper = index;
if (M % 2 == 0) {
looper--;
}
root->childs[3] = NULL; for (int i = 0; i <= looper; i++) {
root->childs[4] = NULL; rhs->childs[i] = root->childs[index + i + 1];
root->childs[index + i + 1] = NULL;
}
rhs->data[0] = root->data[3]; for (int i = 0; i < looper; i++) {
root->data[3] = 0; rhs->data[i] = root->data[index + i + 1];
root->data[index + i + 1] = 0;
}
new->childs[0] = root; new->childs[0] = root;
new->childs[1] = rhs; new->childs[1] = rhs;
new->data[0] = root->data[2]; new->data[0] = root->data[index];
root->data[2] = 0; root->data[index] = 0;
new->count = 1; new->count = 1;
root->count = M/2; root->count = index;
rhs->count = M/2; rhs->count = index;
if (M % 2 == 0) {
rhs->count--;
}
return new; return new;
} }
node* bp_insert_val(node* tree, int val) node *bp_insert_val(node *tree, int val) {
{
// Parse the val into a control struct then insert it in the tree // Parse the val into a control struct then insert it in the tree
control test = bp_insert(tree, value_to_insert(val)); control test = bp_insert(tree, value_to_insert(val));
/* /*
depending on the control item, we act differently depending on the control item, we act differently
if the control has pointers to node, then we had a split in the direct childs of the root. We must add the values upringed to the root if the control has pointers to node, then we had a split in the direct
childs of the root. We must add the values upringed to the root
*/ */
if ( test.rhs != NULL) if (test.rhs != NULL) {
{
/* /*
if the root isn't a leaf, first we add the value into the node if the root isn't a leaf, first we add the value into the node
we can't use bp_insert_into() as if we need a split, the way we do it is slightly different we can't use bp_insert_into() as if we need a split, the way we
do it is slightly different
*/ */
if (!bp_is_leaf(tree)) if (!bp_is_leaf(tree)) {
{ for (int i = 0; i < M; i++) {
for (int i = 0; i < M; i++) if (tree->data[i] == 0) {
{
if (tree->data[i] == 0)
{
tree->childs[i + 1] = test.rhs; tree->childs[i + 1] = test.rhs;
tree->data[i] = test.value; tree->data[i] = test.value;
tree->count++; tree->count++;
...@@ -209,8 +203,7 @@ node* bp_insert_val(node* tree, int val) ...@@ -209,8 +203,7 @@ node* bp_insert_val(node* tree, int val)
} }
// If the root is full, we must split it // If the root is full, we must split it
if (tree->count == M) if (tree->count == M) {
{
return bp_split_root(tree); return bp_split_root(tree);
} }
...@@ -218,7 +211,8 @@ node* bp_insert_val(node* tree, int val) ...@@ -218,7 +211,8 @@ node* bp_insert_val(node* tree, int val)
return tree; return tree;
} }
// if, after a split, the root was a leaf, we must create a new node which will contain the values from the control // if, after a split, the root was a leaf, we must create a new
// node which will contain the values from the control
tree = bp_create_node(); tree = bp_create_node();
tree->childs[0] = test.lhs; tree->childs[0] = test.lhs;
tree->childs[1] = test.rhs; tree->childs[1] = test.rhs;
...@@ -228,16 +222,13 @@ node* bp_insert_val(node* tree, int val) ...@@ -228,16 +222,13 @@ node* bp_insert_val(node* tree, int val)
return tree; return tree;
} }
void bp_destroy(node *root) void bp_destroy(node *root) {
{
if (root == NULL) if (root == NULL)
return; return;
// free the childs first // free the childs first
if (!bp_is_leaf(root)) if (!bp_is_leaf(root)) {
{ for (int i = 0; i < M; i++) {
for (int i = 0; i < M; i++)
{
bp_destroy(root->childs[i]); bp_destroy(root->childs[i]);
} }
} }
...@@ -246,44 +237,36 @@ void bp_destroy(node *root) ...@@ -246,44 +237,36 @@ void bp_destroy(node *root)
free(root); free(root);
} }
void bp_print_as_ll(node *root) void bp_print_as_ll(node *root) {
{
// if we reached the end of the list // if we reached the end of the list
if (root == NULL) if (root == NULL) {
{
printf("NULL\n"); printf("NULL\n");
return; return;
} }
// search for the first leaf on the tree // search for the first leaf on the tree
if (!bp_is_leaf(root)) if (!bp_is_leaf(root)) {
{
return bp_print_as_ll(root->childs[0]); return bp_print_as_ll(root->childs[0]);
} }
printf("|"); printf("|");
// print every values in the node until hitting 0, then we can get on the next node // print every values in the node until hitting 0, then we can get on the
for (int i = 0; i < M; i++) // next node
{ for (int i = 0; i < M; i++) {
printf(" %d |", root->data[i]); printf(" %d |", root->data[i]);
if (root->data[i+1] == 0) if (root->data[i + 1] == 0) {
{
printf(" -> "); printf(" -> ");
return bp_print_as_ll(root->next); return bp_print_as_ll(root->next);
} }
} }
} }
void bp_print(node *root, int depth) void bp_print(node *root, int depth) {
{
// if we are on a leaf, we can print the values directly next to each other // if we are on a leaf, we can print the values directly next to each other
if (bp_is_leaf(root)) if (bp_is_leaf(root)) {
{
for (int i = 0; i < depth; i++) for (int i = 0; i < depth; i++)
printf(" "); printf(" ");
for (int i = 0; i < M; i++) for (int i = 0; i < M; i++) {
{
printf(" %d |", root->data[i]); printf(" %d |", root->data[i]);
// if we reach a 0, we have seen every values in the node // if we reach a 0, we have seen every values in the node
if (root->data[i + 1] == 0) if (root->data[i + 1] == 0)
...@@ -292,8 +275,7 @@ void bp_print(node *root, int depth) ...@@ -292,8 +275,7 @@ void bp_print(node *root, int depth)
return; return;
} }
for (int i = 0; i < M; i++) for (int i = 0; i < M; i++) {
{
bp_print(root->childs[i], depth + 1); bp_print(root->childs[i], depth + 1);
printf("\n"); printf("\n");
......
...@@ -11,25 +11,41 @@ typedef struct node{ ...@@ -11,25 +11,41 @@ typedef struct node{
struct node *next; struct node *next;
} node; } node;
/// @short Print in CLI a B+ Tree /**
/// @param *root Root of the tree to print * @brief Print in CLI a B+ Tree
/// @param depth Always set as 0 *
* @param root Root of the tree to print
* @param depth Always set as 0
*/
void bp_print(node *root, int depth); void bp_print(node *root, int depth);
/// @short Free an entire B+ Tree /**
/// @param *root pointer to the root of the tree to free * @brief Free an entire B+ Tree
*
* @param root pointer to the root of the tree to free
*/
void bp_destroy(node *root); void bp_destroy(node *root);
/// @short Creates a new node of a tree with every values set in a known way /**
/// @return Pointer to new node created * @brief Creates a new node of a tree with every values set in a known way
*
* @return Pointer to new node created
*/
node *bp_create_node(); node *bp_create_node();
/// @short Insert a new int (key) into a B+ Tree /**
/// @param *tree Pointer of the root of the tree * @brief Insert a new int (key) into a B+ Tree
/// @param val Value to insert *
* @param tree Pointer of the root of the tree
* @param val Value to insert
* @return New root of the tree
*/
node *bp_insert_val(node *tree, int val); node *bp_insert_val(node *tree, int val);
/// @short Print in CLI the leaves of the B+ Tree as a linked list /**
/// @param *root Pointer to the root of the tree to print * @brief Print in CLI the leaves of the B+ Tree as a linked list
*
* @param root Pointer to the root of the tree to print
*/
void bp_print_as_ll(node *root); void bp_print_as_ll(node *root);
#endif #endif
...@@ -2,9 +2,7 @@ ...@@ -2,9 +2,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
int int main() {
main ()
{
node *tree = bp_create_node(); node *tree = bp_create_node();
tree = bp_insert_val(tree, 3); tree = bp_insert_val(tree, 3);
...@@ -37,6 +35,15 @@ main () ...@@ -37,6 +35,15 @@ main ()
tree = bp_insert_val(tree, 12); tree = bp_insert_val(tree, 12);
bp_print(tree, 0); bp_print(tree, 0);
printf("\n|||||||||\n"); printf("\n|||||||||\n");
tree = bp_insert_val(tree, 13);
bp_print(tree, 0);
printf("\n|||||||||\n");
tree = bp_insert_val(tree, 14);
bp_print(tree, 0);
printf("\n|||||||||\n");
tree = bp_insert_val(tree, 15);
bp_print(tree, 0);
printf("\n|||||||||\n");
bp_print_as_ll(tree); bp_print_as_ll(tree);
bp_destroy(tree); bp_destroy(tree);
return 0; return 0;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment