Advertisement
Guest User

Binary search tree in C with hashing

a guest
Nov 27th, 2023
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.62 KB | Fixit | 0 0
  1. #ifdef __STDC_LIB_EXT1__
  2.     #define __STDC_WANT_LIB_EXT1__ 1
  3.     #define scanf scanf_s // Bit hacky ngl.
  4. #endif
  5.  
  6. #include <stddef.h> // NULL
  7. #include <stdint.h> // uint64_t, UINT64_MAX
  8. #include <stdio.h>  // scanf()/scanf_s(), puts()
  9. #include <stdlib.h> // malloc(), free()
  10.  
  11. typedef struct {
  12.     unsigned short year;
  13.     unsigned char month, day;
  14.     char *name;
  15. } User;
  16.  
  17. typedef struct BinaryTreeNode {
  18.     struct BinaryTreeNode *left, *right;
  19.     uint64_t hash;
  20. } BinaryTree;
  21.  
  22. #define FNV1A_OFFSET 0xCBF29CE484222325
  23. #define FNV1A_PRIME  0x00000100000001B3
  24.  
  25. static inline uint64_t User_fnv1a_hash(User user) {
  26.     uint64_t hash = FNV1A_OFFSET;
  27.     hash = (hash ^ user.year)  * FNV1A_PRIME;
  28.     hash = (hash ^ user.month) * FNV1A_PRIME;
  29.     hash = (hash ^ user.day)   * FNV1A_PRIME;
  30.     while (*user.name)
  31.         hash = (hash ^ *user.name++) * FNV1A_PRIME;
  32.     return hash;
  33. }
  34.  
  35. static inline BinaryTree *BinaryTree_alloc(uint64_t hash) {
  36.     BinaryTree *tree = (BinaryTree *) malloc(sizeof(BinaryTree));
  37.     tree->left  = NULL;
  38.     tree->right = NULL;
  39.     tree->hash  = hash;
  40.     return tree;
  41. }
  42.  
  43. static inline void BinaryTree_dealloc(BinaryTree *tree) {
  44.     if (tree) {
  45.         BinaryTree_dealloc(tree->left);
  46.         BinaryTree_dealloc(tree->right);
  47.         free(tree);
  48.     }
  49. }
  50.  
  51. BinaryTree *BinaryTree_store(BinaryTree *tree, uint64_t hash) {
  52.     if (tree) {
  53.              if (tree->hash > hash) tree->left  = BinaryTree_store(tree->left,  hash);
  54.         else if (tree->hash < hash) tree->right = BinaryTree_store(tree->right, hash);
  55.         else puts("Already stored");
  56.         return tree;
  57.     }
  58.     puts("Stored");
  59.     return BinaryTree_alloc(hash);
  60. }
  61.  
  62. BinaryTree *BinaryTree_find(BinaryTree *tree, uint64_t hash) {
  63.     if (tree)
  64.              if (tree->hash > hash) tree->left  = BinaryTree_find(tree->left,  hash);
  65.         else if (tree->hash < hash) tree->right = BinaryTree_find(tree->right, hash);
  66.         else puts("Found");
  67.     else puts("Not found");
  68.     return tree;
  69. }
  70.  
  71. static inline uint64_t BinaryTree_find_min_hash(BinaryTree *tree) {
  72.     while (tree->left) tree = tree->left;
  73.     return tree->hash;
  74. }
  75.  
  76. BinaryTree *BinaryTree_delete(BinaryTree *tree, uint64_t hash) {
  77.     if (tree)
  78.              if (tree->hash > hash) tree->left  = BinaryTree_delete(tree->left,  hash);
  79.         else if (tree->hash < hash) tree->right = BinaryTree_delete(tree->right, hash);
  80.         else if (!tree->left && !tree->right) {
  81.             free(tree);
  82.             tree = NULL;
  83.             puts("Deleted");
  84.         }
  85.         else if (!tree->left || !tree->right) {
  86.             BinaryTree *root = tree;
  87.             if (!tree->left)  tree = tree->left;
  88.             if (!tree->right) tree = tree->right;
  89.             free(root);
  90.             puts("Deleted");
  91.         }
  92.         else {
  93.             uint64_t hash = BinaryTree_find_min_hash(tree->right);
  94.             tree->hash  = hash;
  95.             tree->right = BinaryTree_delete(tree, hash);
  96.         }
  97.     else puts("Not found");
  98.     return tree;
  99. }
  100.  
  101. int main() {
  102.     char operation;
  103.     User user;
  104.     BinaryTree *tree = BinaryTree_alloc(UINT64_MAX);
  105.     while (5 == scanf(" %c : %hu %hhu %hhu %m[^\n]",
  106.         &operation,
  107.         &user.year,
  108.         &user.month,
  109.         &user.day,
  110.         &user.name)) {
  111.         uint64_t hash = User_fnv1a_hash(user) % (UINT64_MAX - 1);
  112.         free(user.name);
  113.         switch (operation) {
  114.             case 'S': BinaryTree_store (tree, hash); break;
  115.             case 'F': BinaryTree_find  (tree, hash); break;
  116.             case 'D': BinaryTree_delete(tree, hash); break;
  117.         }
  118.     }
  119.     BinaryTree_dealloc(tree);
  120. }
  121.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement