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

added showcase

parent 3cadeb57
No related branches found
No related tags found
No related merge requests found
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
typedef struct date { typedef struct date {
uint8_t day; uint8_t day;
uint8_t month; // 1 = January, 12 = December uint8_t month; // 1 = January, 12 = December, 0 = Error
uint8_t year; // value stored is year - 1900 uint8_t year; // value stored is year - 1900
} date; } date;
...@@ -37,10 +37,26 @@ typedef struct node { ...@@ -37,10 +37,26 @@ typedef struct node {
*/ */
void bp_print(node *root, int depth); void bp_print(node *root, int depth);
/**
* @brief Factored way to print a single entry
*
* @param person entry to print
*/
void bp_print_entry(entry person); void bp_print_entry(entry person);
/**
* @brief Prints every entries in the tree
*
* @param tree Tree to look into
*/
void bp_print_everything(node *tree); void bp_print_everything(node *tree);
/**
* @brief Search an entry from a phone number
*
* @param tree Tree to look into
* @param phone search parameter
*/
void bp_search(node *tree, char phone[11]); void bp_search(node *tree, char phone[11]);
/** /**
......
...@@ -4,5 +4,11 @@ ...@@ -4,5 +4,11 @@
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
/**
* @brief Generate a 64-bits hash from a string
*
* @param string In this project, send the phone number
* @return uint64_t key
*/
uint64_t generate_key(char *string); uint64_t generate_key(char *string);
#endif #endif
\ No newline at end of file
...@@ -87,14 +87,14 @@ int main() { ...@@ -87,14 +87,14 @@ int main() {
test.year = val - 1900; test.year = val - 1900;
person.birth = test; person.birth = test;
/*
printf("Est-ce valide ? ('y' pour oui)\n"); printf("Est-ce valide ? ('y' pour oui)\n");
bp_print_entry(person); bp_print_entry(person);
scanf("%c", &select); scanf("%s", select);
if (select != 'y') { if (select[0] != 'y') {
goto START; goto START;
}*/ }
tree = bp_insert_val(tree, person); tree = bp_insert_val(tree, person);
break; break;
......
CC=gcc
FLAGS= -Werror
CFLAGS= -g -std=c99
LDFLAGS= -fsanitize=address -fsanitize=leak
exe: showcase
./$^
showcase: showcase.o
$(CC) $^ -o $@ $(CFLAGS) $(LDFLAGS) -lm
showcase.o: showcase.c
$(CC) $(FLAGS) $(CFLAGS) $(LDFLAGS) -c $^
\ No newline at end of file
File added
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
// UTILS ----------------------------------------------------------
#define M 4
#include <stdlib.h>
typedef struct node {
struct node *childs[M + 1];
int data[M];
int count;
struct node *next;
} node;
typedef struct control {
int value;
node *lhs;
node *rhs;
} control;
const control CONST_CONTR = {.value = 0, .lhs = NULL, .rhs = NULL};
node *bp_create_node() {
node *nd = malloc(sizeof(node));
for (int i = 0; i < M + 1; i++)
nd->childs[i] = NULL;
for (int i = 0; i < M; i++)
nd->data[i] = 0;
nd->count = 0;
nd->next = NULL;
return nd;
}
control value_to_insert(int val) {
control c;
c.value = val;
c.lhs = c.rhs = NULL;
return c;
}
bool bp_is_leaf(node *nd) { return nd->childs[0] == NULL; }
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];
for (int i = M - 1; i > index; i--) {
nd->data[i] = nd->data[i - 1];
nd->childs[i + 1] = nd->childs[i];
}
}
node *bp_split(node *nd) {
node *new = bp_create_node();
/*
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++;
}
// no need in this situation to reassign child pointers as there is no
// childs for leaves
for (int i = 0; i < upto; i++) {
new->data[i] = nd->data[index + i];
nd->data[index + i] = 0;
}
return new;
}
node *bp_split_root(node *root) {
node *new = bp_create_node(); // will be the new root
node *rhs = bp_create_node(); // second child of the new root
int index = (int)floor(M / 2); // index to the pivot
int looper = index; /* How many runs of our for loops we'll need to do
(different to index in the case our tree order is even)*/
new->count = 1;
root->count = index;
rhs->count = index;
if (M % 2 == 0) {
looper--;
rhs->count--;
}
// first assing the child pointers
for (int i = 0; i <= looper; i++) {
rhs->childs[i] = root->childs[index + i + 1];
root->childs[index + i + 1] = NULL;
}
// then assing the datas
for (int i = 0; i < looper; i++) {
rhs->data[i] = root->data[index + i + 1];
root->data[index + i + 1] = 0;
}
new->childs[0] = root;
new->childs[1] = rhs;
new->data[0] = root->data[index];
root->data[index] = 0;
return new;
}
control bp_split_unleaf(node *nd) {
// This one is used to split a node that is neither a leaf or a root
// it works exactly like the split of a root except it doesn't return a node
// that becomes the new root
// it instead returns a control value to send to the parent
control new;
node *rhs = bp_create_node();
int index = (int)floor(M / 2);
int looper = index;
nd->count = index;
rhs->count = index;
if (M % 2 == 0) {
looper--;
rhs->count--;
}
for (int i = 0; i <= looper; i++) {
rhs->childs[i] = nd->childs[index + i + 1];
nd->childs[index + i + 1] = NULL;
}
for (int i = 0; i < looper; i++) {
rhs->data[i] = nd->data[index + i + 1];
nd->data[index + i + 1] = 0;
}
new.lhs = nd;
new.rhs = rhs;
new.value = nd->data[index];
nd->data[index] = 0;
return new;
}
void bp_do_the_insert(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++) {
// if we plainly find a 0
if (nd->data[i] == 0) {
nd->data[i] = val.value;
nd->childs[i + 1] = val.rhs;
break;
}
// if we need to insert the value between two values, we need to
// shift everything greater than our value one case further
if (nd->data[i] > val.value) {
bp_node_shift(nd, i);
nd->data[i] = val.value;
nd->childs[i + 1] = val.rhs;
break;
}
}
nd->count++;
}
// INSERT ----------------------------------------------------------
control bp_insert_into(node *nd, control val) {
bp_do_the_insert(nd, val);
// if the node is now full, we split
if (nd->count == M) {
control v;
node *new = bp_split(nd);
v.lhs = nd;
v.rhs = new;
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 (nd->next != NULL)
new->next = nd->next;
nd->next = new;
}
return v;
}
return CONST_CONTR;
}
control bp_insert(node *nd, control val, int depth) {
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))
c = bp_insert_into(nd, val);
else // otherwise let's keep looking
{
for (int i = 0; i < M; i++) {
if (nd->data[i] > val.value || nd->data[i] == 0) {
c = bp_insert(nd->childs[i], val, depth + 1);
break;
}
}
// treat the control return here
// if a split happened and we are not the root
if (c.value != 0 && depth != 0) {
bp_do_the_insert(nd, c);
// if after the child split, the node is full, split the node
if (nd->count == M)
return bp_split_unleaf(nd);
return CONST_CONTR;
}
}
// if a split happened
if (c.value != 0) {
return c;
}
return CONST_CONTR;
}
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), 0);
/*
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 the root isn't a leaf, first we add the value into the node
if (!bp_is_leaf(tree)) {
bp_do_the_insert(tree, test);
// If the root is full, we must split it
if (tree->count == M) {
return bp_split_root(tree);
}
// if not, we can simply return the root
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->childs[0] = test.lhs;
tree->childs[1] = test.rhs;
tree->data[0] = test.value;
tree->count = 1;
}
return tree;
}
// MEMORY ----------------------------------------------------------
void bp_destroy(node *root) {
if (root == NULL)
return;
// free the childs first
if (!bp_is_leaf(root)) {
for (int i = 0; i < M; i++) {
bp_destroy(root->childs[i]);
}
}
// then free the root
free(root);
}
// PRINTING ----------------------------------------------------------
void bp_print_as_ll(node *root) {
// if we reached the end of the list
if (root == NULL) {
printf("NULL\n");
return;
}
// search for the first leaf on the tree
if (!bp_is_leaf(root)) {
return bp_print_as_ll(root->childs[0]);
}
printf("|");
// print every values in the node until hitting 0, then we can get on the
// next node
for (int i = 0; i < M; i++) {
printf(" %d |", root->data[i]);
if (root->data[i + 1] == 0) {
printf(" -> ");
return bp_print_as_ll(root->next);
}
}
}
void bp_print(node *root, int depth) {
// 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++)
printf(" ");
for (int i = 0; i < M; i++) {
printf(" %d |", root->data[i]);
// if we reach a 0, we have seen every values in the node
if (root->data[i + 1] == 0)
break;
}
return;
}
for (int i = 0; i < M; i++) {
bp_print(root->childs[i], depth + 1);
printf("\n");
for (int i = 0; i < depth; i++)
printf(" ");
printf(" %d |\n", root->data[i]);
if (root->data[i + 1] == 0)
return bp_print(root->childs[i + 1], depth + 1);
}
}
int main() {
node *tree = bp_create_node();
tree = bp_insert_val(tree, 3);
bp_print(tree, 0);
printf("\n|||||||||\n");
tree = bp_insert_val(tree, 6);
bp_print(tree, 0);
printf("\n|||||||||\n");
tree = bp_insert_val(tree, 5);
bp_print(tree, 0);
printf("\n|||||||||\n");
tree = bp_insert_val(tree, 4);
bp_print(tree, 0);
printf("\n|||||||||\n");
tree = bp_insert_val(tree, 8);
bp_print(tree, 0);
printf("\n|||||||||\n");
tree = bp_insert_val(tree, 13);
bp_print(tree, 0);
printf("\n|||||||||\n");
tree = bp_insert_val(tree, 9);
bp_print(tree, 0);
printf("\n|||||||||\n");
tree = bp_insert_val(tree, 15);
bp_print(tree, 0);
printf("\n|||||||||\n");
tree = bp_insert_val(tree, 11);
bp_print(tree, 0);
printf("\n|||||||||\n");
tree = bp_insert_val(tree, 12);
bp_print(tree, 0);
printf("\n|||||||||\n");
tree = bp_insert_val(tree, 7);
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, 10);
bp_print(tree, 0);
printf("\n|||||||||\n");
tree = bp_insert_val(tree, 16);
bp_print(tree, 0);
printf("\n|||||||||\n");
tree = bp_insert_val(tree, 17);
bp_print(tree, 0);
printf("\n|||||||||\n");
tree = bp_insert_val(tree, 18);
bp_print(tree, 0);
printf("\n|||||||||\n");
bp_print_as_ll(tree);
bp_destroy(tree);
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment