rb.c (2965B)
1 #include <ctype.h> 2 #include <limits.h> 3 #include <stdio.h> 4 #include <stdint.h> 5 #include <stdlib.h> 6 #include <time.h> 7 8 #include "tree.h" 9 10 #include "config.h" 11 12 typedef struct Node Node; 13 14 15 inline Node * 16 init(int val) 17 { 18 Node *root = emalloc(sizeof(Node)); 19 20 SET_COLOR(root, RED); 21 SET_VALUE(root, val); 22 root->left = NULL; 23 root->right = NULL; 24 25 return root; 26 } 27 28 Node * 29 add(Node *root, int val) 30 { 31 if (!root) 32 return init(val); 33 34 if (val < VALUE(root)) 35 root->left = add(root->left, val); 36 else if (val > VALUE(root)) 37 root->right = add(root->right, val); 38 39 return balance(root); 40 } 41 42 Node * 43 left_turn(Node *root) 44 { 45 Node *n = root->right; 46 root->right = n->left; 47 n->left = root; 48 SET_COLOR(n, COLOR(root)); 49 SET_COLOR(root, RED); 50 return n; 51 } 52 53 Node * 54 right_turn(Node *root) 55 { 56 Node *n = root->left; 57 root->left = n->right; 58 n->right = root; 59 SET_COLOR(n, COLOR(root)); 60 SET_COLOR(root, RED); 61 return n; 62 } 63 64 Node * 65 balance(Node *root) 66 { 67 if (COLOR(root->right) && !COLOR(root->left)) 68 root = left_turn(root); 69 70 if (COLOR(root->left) && COLOR(root->left->left)) 71 root = right_turn(root); 72 73 if (COLOR(root->left) && COLOR(root->right)) { 74 SET_COLOR(root, !COLOR(root)); 75 SET_COLOR(root->left, BLACK); 76 SET_COLOR(root->right, BLACK); 77 } 78 79 return root; 80 } 81 82 83 Node * 84 search(Node *root, int val) 85 { 86 if (VALUE(root) == val) 87 return root; 88 89 if (VALUE(root) > val) 90 return search(root->left, val); 91 92 return search(root->right, val); 93 } 94 95 static inline void 96 usage(void) 97 { 98 eprintf("usage: %s [-c] [-s] [-d] [filename]\n", argv0); 99 } 100 101 int 102 main(int argc, char *argv[]) 103 { 104 int cflag = 0, sflag = 0, dflag = 0; 105 ARGBEGIN { 106 case 'c': 107 cflag = 1; 108 break; 109 case 's': 110 sflag = 1; 111 break; 112 case 'd': 113 eprintf("Not implemented\n"); 114 dflag = 1; 115 break; 116 } ARGEND 117 if (argc > 1 || (cflag + sflag + dflag) < 1) 118 usage(); 119 const char *filename; 120 if (argc == 1) 121 filename = argv[0]; 122 else 123 filename = FILENAME; 124 125 FILE *file; 126 if (!(file = fopen(filename, "r"))) 127 eprintf("fopen %s:", filename); 128 129 int arr[TESTNUMBER+1], ch; 130 char w[64]; 131 int len = 0, wi = 0; 132 do { 133 ch = fgetc(file); 134 if (!isspace(ch) && ch != EOF) { 135 w[wi++] = ch; 136 } else if (wi > 0) { 137 w[wi] = '\0'; 138 arr[len++] = estrtonum(w, 0, INT_MAX); 139 wi = 0; 140 } 141 } while (ch != EOF && len <= TESTNUMBER); 142 efshut(file, filename); 143 if (len < TESTNUMBER) 144 eprintf("Array too small\n"); 145 if (len > TESTNUMBER) 146 weprintf("Array too big - using only the first %d elements\n", TESTNUMBER); 147 148 Node *root = NULL; 149 clock_t start_time, elapsed = 0; 150 151 if (cflag) 152 start_time = clock(); 153 for (int i = 0; i < TESTNUMBER; ++i) { 154 root = add(root, arr[i]); 155 SET_COLOR(root, BLACK); 156 } 157 if (cflag) 158 elapsed += clock() - start_time; 159 160 volatile uintptr_t checksum = 0; /* to avoid optimization */ 161 if (sflag) { 162 start_time = clock(); 163 for (int i = 0; i < TESTNUMBER; ++i) 164 checksum = (uintptr_t)search(root, arr[i]); 165 elapsed += clock() - start_time; 166 } 167 168 printf("%f\n", (double)elapsed/CLOCKS_PER_SEC); 169 }