solution.c (6369B)
1 /* You have to build everything except the main program here 2 * You should not need to write any new code - just gather your 3 * working TreeMap code and the supplied code together from the previous 4 * assignment and combine them together. 5 */ 6 7 struct TreeMapEntry { 8 char *key; /* public */ 9 int value; /* public */ 10 struct TreeMapEntry *__next; 11 struct TreeMapEntry *__left; 12 struct TreeMapEntry *__right; 13 }; 14 15 struct TreeMapIter { 16 struct TreeMapEntry *__current; 17 18 struct TreeMapEntry* (*next)(struct TreeMapIter* self); 19 void (*del)(struct TreeMapIter* self); 20 }; 21 22 struct TreeMap { 23 /* Attributes */ 24 struct TreeMapEntry *__head; 25 struct TreeMapEntry *__root; 26 int __count; 27 int debug; 28 29 /* Methods */ 30 void (*put)(struct TreeMap* self, char *key, int value); 31 int (*get)(struct TreeMap* self, char *key, int def); 32 int (*size)(struct TreeMap* self); 33 void (*dump)(struct TreeMap* self); 34 struct TreeMapIter* (*iter)(struct TreeMap* self); 35 void (*del)(struct TreeMap* self); 36 }; 37 38 void __TreeMap_del(struct TreeMap* self) { 39 struct TreeMapEntry *cur, *next; 40 cur = self->__head; 41 while(cur) { 42 free(cur->key); 43 /* value is just part of the struct */ 44 next = cur->__next; 45 free(cur); 46 cur = next; 47 } 48 free((void *)self); 49 } 50 51 void __TreeMapIter_del(struct TreeMapIter* self) { 52 free((void *)self); 53 } 54 55 void __TreeMap_dump_tree(struct TreeMapEntry *cur, int depth) 56 { 57 int i; 58 if ( cur == NULL ) return; 59 for(i=0;i<depth;i++) printf("| "); 60 printf("%s=%d\n", cur->key, cur->value); 61 if ( cur->__left != NULL ) { 62 __TreeMap_dump_tree(cur->__left, depth+1); 63 } 64 if ( cur->__right != NULL ) { 65 __TreeMap_dump_tree(cur->__right, depth+1); 66 } 67 } 68 69 void __TreeMap_dump(struct TreeMap* self) 70 { 71 struct TreeMapEntry *cur; 72 printf("Object TreeMap count=%d\n", self->__count); 73 for(cur = self->__head; cur != NULL ; cur = cur->__next ) { 74 printf(" %s=%d\n", cur->key, cur->value); 75 } 76 printf("\n"); 77 __TreeMap_dump_tree(self->__root, 0); 78 printf("\n"); 79 } 80 81 /* Run a check to see if left and right are broken */ 82 void __Map_check(struct TreeMap* self, struct TreeMapEntry *left, char *key, struct TreeMapEntry *right) 83 { 84 if ( self->debug ) 85 printf("Check position: %s < %s > %s\n", (left ? left->key : "0"), 86 key, (right ? right->key : "0") ); 87 88 /* Check our location in the linked list */ 89 if ( left != NULL ) { 90 if ( left->__next != right ) { 91 printf("FAIL left->__next != right\n"); 92 } 93 } else { 94 if ( self->__head != right ) { 95 printf("FAIL self->__head != right\n"); 96 } 97 } 98 99 /* Check our location in the tree */ 100 if ( right != NULL && right->__left == NULL ) { 101 /* OK */ 102 } else if ( left != NULL && left->__right == NULL ) { 103 /* OK */ 104 } else { 105 printf("FAIL Neither right->__left nor left->__right are available\n"); 106 } 107 } 108 109 void __TreeMap_put(struct TreeMap* self, char *key, int value) { 110 struct TreeMapEntry *cur, *left, *right; 111 int cmp; 112 struct TreeMapEntry *old, *new; 113 char *new_key; 114 115 cur = self->__root; 116 left = NULL; 117 right = NULL; 118 119 /* TODO: Loop through the tree from the root. If the matches 120 * the node, update the value and return. Ad the tree is scanned, 121 * keep track of the node containing largest key less than "key" 122 * in the variable left and the node containing the smallest key 123 * greater than "key" in the variable "right". So if the key is 124 * not found, left will be the closest lower neighbor or null 125 * and right will be the closest greater neighbor or null. 126 */ 127 128 while (cur != NULL) { 129 cmp = strcmp(key, cur->key); 130 if (cmp == 0) { 131 cur->value = value; 132 return; 133 } 134 135 old = cur; 136 137 if (cmp < 0) { 138 right = cur; 139 cur = cur->__left; 140 } 141 142 if (cmp > 0) { 143 left = cur; 144 cur = cur->__right; 145 } 146 } 147 148 ++self->__count; 149 150 /* Not found - time to insert into the linked list after old */ 151 new = malloc(sizeof(*new)); 152 153 /* TODO: Set up the new node with its new data. */ 154 new_key = malloc(sizeof(*new_key) * (strlen(key) + 1)); 155 new_key = strcpy(new_key, key); 156 new->key = new_key; 157 new->value = value; 158 new->__next = NULL; 159 new->__left = NULL; 160 new->__right = NULL; 161 162 /* Empty list - add first entry */ 163 if ( self->__head == NULL ) { 164 self->__head = new; 165 self->__root = new; 166 return; 167 } 168 169 /* Keep this in here - it will help you debug the above code */ 170 __Map_check(self, left, key, right); 171 172 /* TODO: Insert into the sorted linked list */ 173 if (left == NULL) { 174 new->__next = self->__head; 175 self->__head = new; 176 } else if (right == NULL) { 177 left->__next = new; 178 } else { 179 new->__next = right; 180 left->__next = new; 181 } 182 183 /* TODO: Insert into the tree */ 184 if (cmp > 0) { 185 old->__right = new; 186 } else { 187 old->__left = new; 188 } 189 } 190 191 int __TreeMap_get(struct TreeMap* self, char *key, int def) 192 { 193 int cmp; 194 struct TreeMapEntry *cur; 195 196 if ( self == NULL || key == NULL || self->__root == NULL ) return def; 197 198 cur = self->__root; 199 200 /* TODO: scan down the tree and if the key is found, return the value. 201 * If the key is not found, return the default value (def). 202 */ 203 204 while (cur != NULL) { 205 cmp = strcmp(key, cur->key); 206 if (cmp == 0) { 207 return cur->value; 208 } else if (cmp < 0) { 209 cur = cur->__left; 210 } else { 211 cur = cur->__right; 212 } 213 } 214 215 return def; 216 } 217 218 struct TreeMapEntry* __TreeMapIter_next(struct TreeMapIter* self) 219 { 220 /* Advance the iterator. Recall that when we first 221 * create the iterator __current points to the first item 222 * so we must return an item and then advance the iterator. 223 */ 224 struct TreeMapEntry *cur = self->__current; 225 if (self->__current != NULL) { 226 self->__current = cur->__next; 227 } 228 return cur; 229 } 230 231 int __TreeMap_size(struct TreeMap* self) 232 { 233 return self->__count; 234 } 235 236 struct TreeMapIter* __TreeMap_iter(struct TreeMap* self) 237 { 238 struct TreeMapIter *iter = malloc(sizeof(*iter)); 239 iter->__current = self->__head; 240 iter->next = &__TreeMapIter_next; 241 iter->del = &__TreeMapIter_del; 242 return iter; 243 } 244 245 struct TreeMap * TreeMap_new() { 246 struct TreeMap *p = malloc(sizeof(*p)); 247 248 p->__head = NULL; 249 p->__root = NULL; 250 p->__count = 0; 251 p->debug = 0; 252 253 p->put = &__TreeMap_put; 254 p->get = &__TreeMap_get; 255 p->size = &__TreeMap_size; 256 p->dump = &__TreeMap_dump; 257 p->iter = &__TreeMap_iter; 258 p->del = &__TreeMap_del; 259 return p; 260 }