From a40e3fc3cd9f933e1d02d11985eb7ae8d63ff59b Mon Sep 17 00:00:00 2001 From: Alec <alec.schmidt@hesge.ch> Date: Thu, 16 Jun 2022 10:15:05 +0200 Subject: [PATCH] added showcase --- bp_tree.h | 18 +- hash.h | 6 + main.c | 8 +- showcase/makefile | 13 ++ showcase/showcase | Bin 0 -> 47248 bytes showcase/showcase.c | 419 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 459 insertions(+), 5 deletions(-) create mode 100644 showcase/makefile create mode 100755 showcase/showcase create mode 100644 showcase/showcase.c diff --git a/bp_tree.h b/bp_tree.h index 9190756..0859988 100644 --- a/bp_tree.h +++ b/bp_tree.h @@ -10,7 +10,7 @@ typedef struct date { 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 } date; @@ -37,10 +37,26 @@ typedef struct node { */ 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); +/** + * @brief Prints every entries in the tree + * + * @param tree Tree to look into + */ 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]); /** diff --git a/hash.h b/hash.h index 6496822..6f49ec1 100644 --- a/hash.h +++ b/hash.h @@ -4,5 +4,11 @@ #include <stdint.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); #endif \ No newline at end of file diff --git a/main.c b/main.c index 4a4220c..845cb11 100644 --- a/main.c +++ b/main.c @@ -87,14 +87,14 @@ int main() { test.year = val - 1900; person.birth = test; - /* + printf("Est-ce valide ? ('y' pour oui)\n"); bp_print_entry(person); - scanf("%c", &select); - if (select != 'y') { + scanf("%s", select); + if (select[0] != 'y') { goto START; - }*/ + } tree = bp_insert_val(tree, person); break; diff --git a/showcase/makefile b/showcase/makefile new file mode 100644 index 0000000..959275c --- /dev/null +++ b/showcase/makefile @@ -0,0 +1,13 @@ +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 diff --git a/showcase/showcase b/showcase/showcase new file mode 100755 index 0000000000000000000000000000000000000000..1764eaf4b94576facef276da61225d822be59fbd GIT binary patch literal 47248 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 literal 0 HcmV?d00001 diff --git a/showcase/showcase.c b/showcase/showcase.c new file mode 100644 index 0000000..a0b401c --- /dev/null +++ b/showcase/showcase.c @@ -0,0 +1,419 @@ +#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; +} -- GitLab