Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifdef __STDC_LIB_EXT1__
- #define __STDC_WANT_LIB_EXT1__ 1
- #define scanf scanf_s // Bit hacky ngl.
- #endif
- #include <stddef.h> // NULL
- #include <stdint.h> // uint64_t, UINT64_MAX
- #include <stdio.h> // scanf()/scanf_s(), puts()
- #include <stdlib.h> // malloc(), free()
- typedef struct {
- unsigned short year;
- unsigned char month, day;
- char *name;
- } User;
- typedef struct BinaryTreeNode {
- struct BinaryTreeNode *left, *right;
- uint64_t hash;
- } BinaryTree;
- #define FNV1A_OFFSET 0xCBF29CE484222325
- #define FNV1A_PRIME 0x00000100000001B3
- static inline uint64_t User_fnv1a_hash(User user) {
- uint64_t hash = FNV1A_OFFSET;
- hash = (hash ^ user.year) * FNV1A_PRIME;
- hash = (hash ^ user.month) * FNV1A_PRIME;
- hash = (hash ^ user.day) * FNV1A_PRIME;
- while (*user.name)
- hash = (hash ^ *user.name++) * FNV1A_PRIME;
- return hash;
- }
- static inline BinaryTree *BinaryTree_alloc(uint64_t hash) {
- BinaryTree *tree = (BinaryTree *) malloc(sizeof(BinaryTree));
- tree->left = NULL;
- tree->right = NULL;
- tree->hash = hash;
- return tree;
- }
- static inline void BinaryTree_dealloc(BinaryTree *tree) {
- if (tree) {
- BinaryTree_dealloc(tree->left);
- BinaryTree_dealloc(tree->right);
- free(tree);
- }
- }
- BinaryTree *BinaryTree_store(BinaryTree *tree, uint64_t hash) {
- if (tree) {
- if (tree->hash > hash) tree->left = BinaryTree_store(tree->left, hash);
- else if (tree->hash < hash) tree->right = BinaryTree_store(tree->right, hash);
- else puts("Already stored");
- return tree;
- }
- puts("Stored");
- return BinaryTree_alloc(hash);
- }
- BinaryTree *BinaryTree_find(BinaryTree *tree, uint64_t hash) {
- if (tree)
- if (tree->hash > hash) tree->left = BinaryTree_find(tree->left, hash);
- else if (tree->hash < hash) tree->right = BinaryTree_find(tree->right, hash);
- else puts("Found");
- else puts("Not found");
- return tree;
- }
- static inline uint64_t BinaryTree_find_min_hash(BinaryTree *tree) {
- while (tree->left) tree = tree->left;
- return tree->hash;
- }
- BinaryTree *BinaryTree_delete(BinaryTree *tree, uint64_t hash) {
- if (tree)
- if (tree->hash > hash) tree->left = BinaryTree_delete(tree->left, hash);
- else if (tree->hash < hash) tree->right = BinaryTree_delete(tree->right, hash);
- else if (!tree->left && !tree->right) {
- free(tree);
- tree = NULL;
- puts("Deleted");
- }
- else if (!tree->left || !tree->right) {
- BinaryTree *root = tree;
- if (!tree->left) tree = tree->left;
- if (!tree->right) tree = tree->right;
- free(root);
- puts("Deleted");
- }
- else {
- uint64_t hash = BinaryTree_find_min_hash(tree->right);
- tree->hash = hash;
- tree->right = BinaryTree_delete(tree, hash);
- }
- else puts("Not found");
- return tree;
- }
- int main() {
- char operation;
- User user;
- BinaryTree *tree = BinaryTree_alloc(UINT64_MAX);
- while (5 == scanf(" %c : %hu %hhu %hhu %m[^\n]",
- &operation,
- &user.year,
- &user.month,
- &user.day,
- &user.name)) {
- uint64_t hash = User_fnv1a_hash(user) % (UINT64_MAX - 1);
- free(user.name);
- switch (operation) {
- case 'S': BinaryTree_store (tree, hash); break;
- case 'F': BinaryTree_find (tree, hash); break;
- case 'D': BinaryTree_delete(tree, hash); break;
- }
- }
- BinaryTree_dealloc(tree);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement