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

library commented

parent 44365830
No related branches found
No related tags found
No related merge requests found
...@@ -4,6 +4,12 @@ ...@@ -4,6 +4,12 @@
#include <stdbool.h> #include <stdbool.h>
#include <math.h> #include <math.h>
typedef struct control{
int value;
node *lhs;
node *rhs;
}control;
const control CONST_CONTR = { const control CONST_CONTR = {
.value = 0, .value = 0,
.lhs = NULL, .lhs = NULL,
...@@ -35,7 +41,9 @@ bool bp_is_leaf(node *nd) {return nd->childs[0] == NULL;} ...@@ -35,7 +41,9 @@ 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 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];
...@@ -46,28 +54,50 @@ void bp_node_shift(node *nd, int index) ...@@ -46,28 +54,50 @@ void bp_node_shift(node *nd, int index)
node* bp_split(node *nd) node* bp_split(node *nd)
{ {
node *new = bp_create_node(); node *new = bp_create_node();
for (int i = 0; i < M/2; i++) /*
this weird thing is for the for loop
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
*/
int upto = (int)floor(M/2);
int index = upto;
// update the new counts
nd->count = (int)floor(nd->count/2);
new->count = upto;
// as explained, do shit if the order is odd
if (M%2 == 1)
{
upto++;
new->count++;
}
for (int i = 0; i < upto; i++)
{ {
new->data[i] = nd->data[M/2 + i]; new->data[i] = nd->data[index + i];
nd->data[M/2 + i] = 0; nd->data[index + i] = 0;
new->childs[i] = nd->childs[M/2 + i]; new->childs[i] = nd->childs[index + i];
nd->childs[M/2 + i] = NULL; nd->childs[index + i] = NULL;
} }
nd->count /=2;
new->count = M/2;
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 the algorithm)
for (int i = 0; i < M; i++) for (int i = 0; i < M; i++)
{ {
// 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 (nd->data[i] > val.value) if (nd->data[i] > val.value)
{ {
bp_node_shift(nd, i); bp_node_shift(nd, i);
...@@ -78,7 +108,7 @@ control bp_insert_into(node *nd, control val) ...@@ -78,7 +108,7 @@ control bp_insert_into(node *nd, control val)
} }
nd->count++; nd->count++;
// if the node is now full, we split
if (nd->count == M) if (nd->count == M)
{ {
control v; control v;
...@@ -86,20 +116,23 @@ control bp_insert_into(node *nd, control val) ...@@ -86,20 +116,23 @@ control bp_insert_into(node *nd, control val)
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 (bp_is_leaf(new)) if (bp_is_leaf(new))
nd->next = new; nd->next = new;
return v; return v;
} }
return CONST_CONTR; return CONST_CONTR;
} }
control bp_insert(node *nd, control val){ control bp_insert(node *nd, control val){
control c; 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 (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
{ {
for (int i = 0; i < M; i++) for (int i = 0; i < M; i++)
{ {
...@@ -109,9 +142,8 @@ control bp_insert(node *nd, control val){ ...@@ -109,9 +142,8 @@ control bp_insert(node *nd, control val){
break; break;
} }
} }
//c = bp_insert_into(nd, c);
} }
// Si il y a eu un split // if a split happened
if (c.value != 0) if (c.value != 0)
{ {
return c; return c;
...@@ -121,6 +153,7 @@ control bp_insert(node *nd, control val){ ...@@ -121,6 +153,7 @@ control bp_insert(node *nd, control val){
node* bp_split_root(node *root) node* bp_split_root(node *root)
{ {
// 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();
...@@ -147,12 +180,21 @@ node* bp_split_root(node *root) ...@@ -147,12 +180,21 @@ node* bp_split_root(node *root)
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
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
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
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++)
...@@ -166,16 +208,17 @@ node* bp_insert_val(node* tree, int val) ...@@ -166,16 +208,17 @@ node* bp_insert_val(node* tree, int val)
} }
} }
/* GROS ICI SI LA RACINE N'EST PAS UNE FEUILLE ET QU'APRES AVOIR REMONTE UNE VALEUR LA RACINE EST PLEINE, IL FAUT SPLIT LA RACINE */ // If the root is full, we must split it
printf("%d\n", tree->count);
if (tree->count == M) if (tree->count == M)
{ {
return bp_split_root(tree); return bp_split_root(tree);
} }
//if not, we can simply return the root
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
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;
...@@ -185,58 +228,64 @@ node* bp_insert_val(node* tree, int val) ...@@ -185,58 +228,64 @@ node* bp_insert_val(node* tree, int val)
return tree; return tree;
} }
void bp_destroy(node *nd) void bp_destroy(node *root)
{ {
if (nd == NULL) if (root == NULL)
return; return;
if (!bp_is_leaf(nd)) // free the childs first
if (!bp_is_leaf(root))
{ {
for (int i = 0; i < M; i++) for (int i = 0; i < M; i++)
{ {
bp_destroy(nd->childs[i]); bp_destroy(root->childs[i]);
} }
} }
//free(nd->childs);
free(nd);
}
// then free the root
free(root);
}
void bp_print_as_ll(node *nd) void bp_print_as_ll(node *root)
{ {
if (nd == NULL) // if we reached the end of the list
if (root == NULL)
{ {
printf("NULL\n"); printf("NULL\n");
return; return;
} }
if (!bp_is_leaf(nd)) // search for the first leaf on the tree
if (!bp_is_leaf(root))
{ {
return bp_print_as_ll(nd->childs[0]); return bp_print_as_ll(root->childs[0]);
} }
// print every values in the node until hitting 0, then we can get on the next node
for (int i = 0; i < M; i++) for (int i = 0; i < M; i++)
{ {
printf(" %d |", nd->data[i]); printf(" %d |", root->data[i]);
if (nd->data[i+1] == 0) if (root->data[i+1] == 0)
{ {
printf("->"); printf("->");
return bp_print_as_ll(nd->next); return bp_print_as_ll(root->next);
} }
} }
} }
void bp_print(node *nd, int depth) void bp_print(node *root, int depth)
{ {
if (bp_is_leaf(nd)) // if we are on a leaf, we can print the values directly next to each other
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 |", nd->data[i]); printf(" %d |", root->data[i]);
if (nd->data[i+1] == 0) // if we reach a 0, we have seen every values in the node
if (root->data[i+1] == 0)
break; break;
} }
printf("\n"); printf("\n");
...@@ -244,19 +293,18 @@ void bp_print(node *nd, int depth) ...@@ -244,19 +293,18 @@ void bp_print(node *nd, int depth)
} }
for (int i = 0; i < M; i++) for (int i = 0; i < M; i++)
{ {
printf("\n"); printf("\n");
bp_print(nd->childs[i], depth + 1); bp_print(root->childs[i], depth + 1);
for (int i = 0; i < depth; i++) for (int i = 0; i < depth; i++)
printf(" "); printf(" ");
printf(" %d |", nd->data[i]); printf(" %d |", root->data[i]);
if (nd->data[i+1] == 0) if (root->data[i+1] == 0)
{ {
printf("\n"); printf("\n");
return bp_print(nd->childs[i+1], depth + 1); return bp_print(root->childs[i+1], depth + 1);
} }
} }
} }
\ No newline at end of file
#ifndef _BP_TREE_C_ #ifndef _BP_TREE_C_
#define _BP_TREE_C_ #define _BP_TREE_C_
#define M 4 #define M 5
#include <stdlib.h> #include <stdlib.h>
typedef struct node{ typedef struct node{
...@@ -11,17 +11,25 @@ typedef struct node{ ...@@ -11,17 +11,25 @@ typedef struct node{
struct node *next; struct node *next;
}node; }node;
typedef struct control{ /// @short Print in CLI a B+ Tree
int value; /// @param *root Root of the tree to print
node *lhs; /// @param depth Always set as 0
node *rhs; void bp_print(node *root, int depth);
}control;
extern const control CONST_CONTR; /// @short Free an entire B+ Tree
/// @param *root pointer to the root of the tree to free
void bp_destroy(node *root);
void bp_print(node *nd, int depth); /// @short Creates a new node of a tree with every values set in a known way
void bp_destroy(node *nd); /// @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
/// @param val Value to insert
node* bp_insert_val(node* tree, int val); node* bp_insert_val(node* tree, int val);
void bp_print_as_ll(node *nd);
/// @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
void bp_print_as_ll(node *root);
#endif #endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment