Snake
Dependencies: mbed wave_player 4DGL-uLCD-SE MMA8452
hash_table.cpp@3:2fe73b263a9a, 2020-11-23 (annotated)
- Committer:
- congvu
- Date:
- Mon Nov 23 05:54:49 2020 +0000
- Revision:
- 3:2fe73b263a9a
- Parent:
- 2:4947d6a82971
ECE2035;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
DCchico | 1:10330bce85cb | 1 | /* |
congvu | 3:2fe73b263a9a | 2 | Student Name: Cong Vu |
congvu | 3:2fe73b263a9a | 3 | Date: 11/01/2020 |
DCchico | 1:10330bce85cb | 4 | ======================= |
DCchico | 1:10330bce85cb | 5 | ECE 2035 Project 2-1: |
DCchico | 1:10330bce85cb | 6 | ======================= |
DCchico | 1:10330bce85cb | 7 | This file provides definition for the structs and functions declared in the |
DCchico | 1:10330bce85cb | 8 | header file. It also contains helper functions that are not accessible from |
DCchico | 1:10330bce85cb | 9 | outside of the file. |
DCchico | 1:10330bce85cb | 10 | FOR FULL CREDIT, BE SURE TO TRY MULTIPLE TEST CASES and DOCUMENT YOUR CODE. |
DCchico | 1:10330bce85cb | 11 | =================================== |
DCchico | 1:10330bce85cb | 12 | Naming conventions in this file: |
DCchico | 1:10330bce85cb | 13 | =================================== |
DCchico | 1:10330bce85cb | 14 | 1. All struct names use camel case where the first letter is capitalized. |
congvu | 3:2fe73b263a9a | 15 | e.g. "HashTable", or "HashTableEntry" |
DCchico | 1:10330bce85cb | 16 | 2. Variable names with a preceding underscore "_" will not be called directly. |
congvu | 3:2fe73b263a9a | 17 | e.g. "_HashTable", "_HashTableEntry" |
congvu | 3:2fe73b263a9a | 18 | Recall that in C, we have to type "struct" together with the name of the struct |
congvu | 3:2fe73b263a9a | 19 | in order to initialize a new variable. To avoid this, in hash_table.h |
congvu | 3:2fe73b263a9a | 20 | we use typedef to provide new "nicknames" for "struct _HashTable" and |
congvu | 3:2fe73b263a9a | 21 | "struct _HashTableEntry". As a result, we can create new struct variables |
congvu | 3:2fe73b263a9a | 22 | by just using: |
congvu | 3:2fe73b263a9a | 23 | - "HashTable myNewTable;" |
congvu | 3:2fe73b263a9a | 24 | or |
congvu | 3:2fe73b263a9a | 25 | - "HashTableEntry myNewHashTableEntry;" |
congvu | 3:2fe73b263a9a | 26 | The preceding underscore "_" simply provides a distinction between the names |
congvu | 3:2fe73b263a9a | 27 | of the actual struct defition and the "nicknames" that we use to initialize |
congvu | 3:2fe73b263a9a | 28 | new structs. |
congvu | 3:2fe73b263a9a | 29 | [See Hidden Definitions section for more information.] |
DCchico | 1:10330bce85cb | 30 | 3. Functions, their local variables and arguments are named with camel case, where |
congvu | 3:2fe73b263a9a | 31 | the first letter is lower-case. |
congvu | 3:2fe73b263a9a | 32 | e.g. "createHashTable" is a function. One of its arguments is "numBuckets". |
congvu | 3:2fe73b263a9a | 33 | It also has a local variable called "newTable". |
DCchico | 1:10330bce85cb | 34 | 4. The name of a struct member is divided by using underscores "_". This serves |
congvu | 3:2fe73b263a9a | 35 | as a distinction between function local variables and struct members. |
congvu | 3:2fe73b263a9a | 36 | e.g. "num_buckets" is a member of "HashTable". |
DCchico | 1:10330bce85cb | 37 | */ |
congvu | 3:2fe73b263a9a | 38 | |
DCchico | 1:10330bce85cb | 39 | /**************************************************************************** |
DCchico | 1:10330bce85cb | 40 | * Include the Public Interface |
DCchico | 1:10330bce85cb | 41 | * |
DCchico | 1:10330bce85cb | 42 | * By including the public interface at the top of the file, the compiler can |
DCchico | 1:10330bce85cb | 43 | * enforce that the function declarations in the the header are not in |
DCchico | 1:10330bce85cb | 44 | * conflict with the definitions in the file. This is not a guarantee of |
DCchico | 1:10330bce85cb | 45 | * correctness, but it is better than nothing! |
DCchico | 1:10330bce85cb | 46 | ***************************************************************************/ |
DCchico | 1:10330bce85cb | 47 | #include "hash_table.h" |
congvu | 3:2fe73b263a9a | 48 | |
congvu | 3:2fe73b263a9a | 49 | |
DCchico | 1:10330bce85cb | 50 | /**************************************************************************** |
DCchico | 1:10330bce85cb | 51 | * Include other private dependencies |
DCchico | 1:10330bce85cb | 52 | * |
DCchico | 1:10330bce85cb | 53 | * These other modules are used in the implementation of the hash table module, |
DCchico | 1:10330bce85cb | 54 | * but are not required by users of the hash table. |
DCchico | 1:10330bce85cb | 55 | ***************************************************************************/ |
DCchico | 1:10330bce85cb | 56 | #include <stdlib.h> // For malloc and free |
DCchico | 1:10330bce85cb | 57 | #include <stdio.h> // For printf |
congvu | 3:2fe73b263a9a | 58 | |
congvu | 3:2fe73b263a9a | 59 | |
DCchico | 1:10330bce85cb | 60 | /**************************************************************************** |
DCchico | 1:10330bce85cb | 61 | * Hidden Definitions |
DCchico | 1:10330bce85cb | 62 | * |
DCchico | 1:10330bce85cb | 63 | * These definitions are not available outside of this file. However, because |
DCchico | 1:10330bce85cb | 64 | * the are forward declared in hash_table.h, the type names are |
DCchico | 1:10330bce85cb | 65 | * available everywhere and user code can hold pointers to these structs. |
DCchico | 1:10330bce85cb | 66 | ***************************************************************************/ |
DCchico | 1:10330bce85cb | 67 | /** |
congvu | 3:2fe73b263a9a | 68 | * This structure represents an hash table. |
congvu | 3:2fe73b263a9a | 69 | * Use "HashTable" instead when you are creating a new variable. [See top comments] |
congvu | 3:2fe73b263a9a | 70 | */ |
DCchico | 1:10330bce85cb | 71 | struct _HashTable { |
DCchico | 1:10330bce85cb | 72 | /** The array of pointers to the head of a singly linked list, whose nodes |
congvu | 3:2fe73b263a9a | 73 | are HashTableEntry objects */ |
DCchico | 1:10330bce85cb | 74 | HashTableEntry** buckets; |
congvu | 3:2fe73b263a9a | 75 | |
DCchico | 1:10330bce85cb | 76 | /** The hash function pointer */ |
DCchico | 1:10330bce85cb | 77 | HashFunction hash; |
congvu | 3:2fe73b263a9a | 78 | |
DCchico | 1:10330bce85cb | 79 | /** The number of buckets in the hash table */ |
DCchico | 1:10330bce85cb | 80 | unsigned int num_buckets; |
DCchico | 1:10330bce85cb | 81 | }; |
congvu | 3:2fe73b263a9a | 82 | |
DCchico | 1:10330bce85cb | 83 | /** |
congvu | 3:2fe73b263a9a | 84 | * This structure represents a hash table entry. |
congvu | 3:2fe73b263a9a | 85 | * Use "HashTableEntry" instead when you are creating a new variable. [See top comments] |
congvu | 3:2fe73b263a9a | 86 | */ |
DCchico | 1:10330bce85cb | 87 | struct _HashTableEntry { |
DCchico | 1:10330bce85cb | 88 | /** The key for the hash table entry */ |
DCchico | 1:10330bce85cb | 89 | unsigned int key; |
congvu | 3:2fe73b263a9a | 90 | |
DCchico | 1:10330bce85cb | 91 | /** The value associated with this hash table entry */ |
DCchico | 1:10330bce85cb | 92 | void* value; |
congvu | 3:2fe73b263a9a | 93 | |
DCchico | 1:10330bce85cb | 94 | /** |
DCchico | 1:10330bce85cb | 95 | * A pointer pointing to the next hash table entry |
DCchico | 1:10330bce85cb | 96 | * NULL means there is no next entry (i.e. this is the tail) |
DCchico | 1:10330bce85cb | 97 | */ |
DCchico | 1:10330bce85cb | 98 | HashTableEntry* next; |
DCchico | 1:10330bce85cb | 99 | }; |
congvu | 3:2fe73b263a9a | 100 | |
congvu | 3:2fe73b263a9a | 101 | |
DCchico | 1:10330bce85cb | 102 | /**************************************************************************** |
DCchico | 1:10330bce85cb | 103 | * Private Functions |
DCchico | 1:10330bce85cb | 104 | * |
DCchico | 1:10330bce85cb | 105 | * These functions are not available outside of this file, since they are not |
DCchico | 1:10330bce85cb | 106 | * declared in hash_table.h. |
DCchico | 1:10330bce85cb | 107 | ***************************************************************************/ |
DCchico | 1:10330bce85cb | 108 | /** |
DCchico | 1:10330bce85cb | 109 | * createHashTableEntry |
DCchico | 1:10330bce85cb | 110 | * |
DCchico | 1:10330bce85cb | 111 | * Helper function that creates a hash table entry by allocating memory for it on |
DCchico | 1:10330bce85cb | 112 | * the heap. It initializes the entry with key and value, initialize pointer to |
DCchico | 1:10330bce85cb | 113 | * the next entry as NULL, and return the pointer to this hash table entry. |
DCchico | 1:10330bce85cb | 114 | * |
DCchico | 1:10330bce85cb | 115 | * @param key The key corresponds to the hash table entry |
DCchico | 1:10330bce85cb | 116 | * @param value The value stored in the hash table entry |
DCchico | 1:10330bce85cb | 117 | * @return The pointer to the hash table entry |
DCchico | 1:10330bce85cb | 118 | */ |
congvu | 3:2fe73b263a9a | 119 | static HashTableEntry* createHashTableEntry(unsigned int key, void *value) { |
congvu | 3:2fe73b263a9a | 120 | |
congvu | 3:2fe73b263a9a | 121 | HashTableEntry* newEntry = (HashTableEntry*)malloc(sizeof(HashTableEntry)); |
congvu | 3:2fe73b263a9a | 122 | newEntry ->key = key; |
congvu | 3:2fe73b263a9a | 123 | newEntry ->value = value; |
congvu | 3:2fe73b263a9a | 124 | newEntry ->next = NULL; |
congvu | 3:2fe73b263a9a | 125 | |
congvu | 3:2fe73b263a9a | 126 | return newEntry; |
DCchico | 1:10330bce85cb | 127 | } |
congvu | 3:2fe73b263a9a | 128 | |
DCchico | 1:10330bce85cb | 129 | /** |
DCchico | 1:10330bce85cb | 130 | * findItem |
DCchico | 1:10330bce85cb | 131 | * |
DCchico | 1:10330bce85cb | 132 | * Helper function that checks whether there exists the hash table entry that |
DCchico | 1:10330bce85cb | 133 | * contains a specific key. |
DCchico | 1:10330bce85cb | 134 | * |
DCchico | 1:10330bce85cb | 135 | * @param hashTable The pointer to the hash table. |
DCchico | 1:10330bce85cb | 136 | * @param key The key corresponds to the hash table entry |
DCchico | 1:10330bce85cb | 137 | * @return The pointer to the hash table entry, or NULL if key does not exist |
DCchico | 1:10330bce85cb | 138 | */ |
congvu | 3:2fe73b263a9a | 139 | static HashTableEntry* findItem(HashTable* hashTable, unsigned int key) { |
congvu | 3:2fe73b263a9a | 140 | |
congvu | 3:2fe73b263a9a | 141 | //get which bucket |
congvu | 3:2fe73b263a9a | 142 | int bucketIndex = hashTable -> hash(key); |
congvu | 3:2fe73b263a9a | 143 | |
congvu | 3:2fe73b263a9a | 144 | /** |
congvu | 3:2fe73b263a9a | 145 | * set thisNode to head of bucket we are looking in |
congvu | 3:2fe73b263a9a | 146 | */ |
congvu | 3:2fe73b263a9a | 147 | HashTableEntry *thisNode = hashTable->buckets[bucketIndex]; |
congvu | 3:2fe73b263a9a | 148 | |
congvu | 3:2fe73b263a9a | 149 | while(thisNode) //while not null |
congvu | 3:2fe73b263a9a | 150 | { |
congvu | 3:2fe73b263a9a | 151 | if(thisNode -> key == key) return thisNode; //if equal, return that entry |
congvu | 3:2fe73b263a9a | 152 | thisNode = thisNode->next;//if not, get next entry |
congvu | 3:2fe73b263a9a | 153 | } |
congvu | 3:2fe73b263a9a | 154 | return thisNode; // return value, null if not found |
DCchico | 1:10330bce85cb | 155 | } |
congvu | 3:2fe73b263a9a | 156 | |
congvu | 3:2fe73b263a9a | 157 | |
DCchico | 1:10330bce85cb | 158 | /**************************************************************************** |
DCchico | 1:10330bce85cb | 159 | * Public Interface Functions |
DCchico | 1:10330bce85cb | 160 | * |
DCchico | 1:10330bce85cb | 161 | * These functions implement the public interface as specified in the header |
DCchico | 1:10330bce85cb | 162 | * file, and make use of the private functions and hidden definitions in the |
DCchico | 1:10330bce85cb | 163 | * above sections. |
DCchico | 1:10330bce85cb | 164 | ****************************************************************************/ |
DCchico | 1:10330bce85cb | 165 | // The createHashTable is provided for you as a starting point. |
DCchico | 1:10330bce85cb | 166 | HashTable* createHashTable(HashFunction hashFunction, unsigned int numBuckets) { |
DCchico | 1:10330bce85cb | 167 | // The hash table has to contain at least one bucket. Exit gracefully if |
DCchico | 1:10330bce85cb | 168 | // this condition is not met. |
DCchico | 1:10330bce85cb | 169 | if (numBuckets==0) { |
DCchico | 1:10330bce85cb | 170 | printf("Hash table has to contain at least 1 bucket...\n"); |
DCchico | 1:10330bce85cb | 171 | exit(1); |
DCchico | 1:10330bce85cb | 172 | } |
congvu | 3:2fe73b263a9a | 173 | |
DCchico | 1:10330bce85cb | 174 | // Allocate memory for the new HashTable struct on heap. |
DCchico | 1:10330bce85cb | 175 | HashTable* newTable = (HashTable*)malloc(sizeof(HashTable)); |
congvu | 3:2fe73b263a9a | 176 | |
DCchico | 1:10330bce85cb | 177 | // Initialize the components of the new HashTable struct. |
DCchico | 1:10330bce85cb | 178 | newTable->hash = hashFunction; |
DCchico | 1:10330bce85cb | 179 | newTable->num_buckets = numBuckets; |
DCchico | 1:10330bce85cb | 180 | newTable->buckets = (HashTableEntry**)malloc(numBuckets*sizeof(HashTableEntry*)); |
congvu | 3:2fe73b263a9a | 181 | |
DCchico | 1:10330bce85cb | 182 | // As the new buckets are empty, init each bucket as NULL. |
DCchico | 1:10330bce85cb | 183 | unsigned int i; |
DCchico | 1:10330bce85cb | 184 | for (i=0; i<numBuckets; ++i) { |
DCchico | 1:10330bce85cb | 185 | newTable->buckets[i] = NULL; |
DCchico | 1:10330bce85cb | 186 | } |
congvu | 3:2fe73b263a9a | 187 | |
DCchico | 1:10330bce85cb | 188 | // Return the new HashTable struct. |
DCchico | 1:10330bce85cb | 189 | return newTable; |
DCchico | 1:10330bce85cb | 190 | } |
congvu | 3:2fe73b263a9a | 191 | |
congvu | 3:2fe73b263a9a | 192 | |
DCchico | 1:10330bce85cb | 193 | void destroyHashTable(HashTable* hashTable) { |
congvu | 3:2fe73b263a9a | 194 | |
congvu | 3:2fe73b263a9a | 195 | int i; |
congvu | 3:2fe73b263a9a | 196 | //iterate through all all buckets, if 4 buckets, final value of i is 3 |
congvu | 3:2fe73b263a9a | 197 | for (i = 0; i< (hashTable -> num_buckets); i++) |
congvu | 3:2fe73b263a9a | 198 | { |
congvu | 3:2fe73b263a9a | 199 | //if bucket's head entry is not null, delete all entries |
congvu | 3:2fe73b263a9a | 200 | if(hashTable -> buckets[i]) |
congvu | 3:2fe73b263a9a | 201 | { |
congvu | 3:2fe73b263a9a | 202 | //keep track of currentNode |
congvu | 3:2fe73b263a9a | 203 | HashTableEntry* thisNode = hashTable -> buckets[i]; |
congvu | 3:2fe73b263a9a | 204 | //keep track of nextNode so can iterate until there is only |
congvu | 3:2fe73b263a9a | 205 | //one entry left in bucket |
congvu | 3:2fe73b263a9a | 206 | HashTableEntry *nextNode = thisNode -> next; |
congvu | 3:2fe73b263a9a | 207 | |
congvu | 3:2fe73b263a9a | 208 | while(nextNode) |
congvu | 3:2fe73b263a9a | 209 | { |
congvu | 3:2fe73b263a9a | 210 | //destroy thisNode and all its variables |
congvu | 3:2fe73b263a9a | 211 | free(thisNode -> value); |
congvu | 3:2fe73b263a9a | 212 | free(thisNode); |
congvu | 3:2fe73b263a9a | 213 | //update thisNode and nextNode |
congvu | 3:2fe73b263a9a | 214 | thisNode = nextNode; |
congvu | 3:2fe73b263a9a | 215 | nextNode = nextNode ->next; |
congvu | 3:2fe73b263a9a | 216 | } |
congvu | 3:2fe73b263a9a | 217 | //delete the final remaining entry, the tail |
congvu | 3:2fe73b263a9a | 218 | free(thisNode); |
congvu | 3:2fe73b263a9a | 219 | } |
congvu | 3:2fe73b263a9a | 220 | } |
congvu | 3:2fe73b263a9a | 221 | //destroy hashTable |
congvu | 3:2fe73b263a9a | 222 | free(hashTable); |
congvu | 3:2fe73b263a9a | 223 | return; |
DCchico | 1:10330bce85cb | 224 | } |
congvu | 3:2fe73b263a9a | 225 | |
DCchico | 1:10330bce85cb | 226 | void* insertItem(HashTable* hashTable, unsigned int key, void* value) { |
congvu | 3:2fe73b263a9a | 227 | |
congvu | 3:2fe73b263a9a | 228 | //get which bucket to insert into |
congvu | 3:2fe73b263a9a | 229 | int bucketIndex = hashTable -> hash(key); |
congvu | 3:2fe73b263a9a | 230 | |
congvu | 3:2fe73b263a9a | 231 | /** |
congvu | 3:2fe73b263a9a | 232 | * If there exists entry with passed in key, change its value |
congvu | 3:2fe73b263a9a | 233 | */ |
congvu | 3:2fe73b263a9a | 234 | HashTableEntry *existNode = findItem(hashTable,key); |
congvu | 3:2fe73b263a9a | 235 | if(existNode) |
congvu | 3:2fe73b263a9a | 236 | { |
congvu | 3:2fe73b263a9a | 237 | //make copy of exisiting value |
congvu | 3:2fe73b263a9a | 238 | void* oldValue; |
congvu | 3:2fe73b263a9a | 239 | oldValue = existNode -> value; |
congvu | 3:2fe73b263a9a | 240 | //update value |
congvu | 3:2fe73b263a9a | 241 | existNode -> value = value; |
congvu | 3:2fe73b263a9a | 242 | //return value that is replaced |
congvu | 3:2fe73b263a9a | 243 | return oldValue; |
congvu | 3:2fe73b263a9a | 244 | } |
congvu | 3:2fe73b263a9a | 245 | |
congvu | 3:2fe73b263a9a | 246 | //create new entry with specified key and value |
congvu | 3:2fe73b263a9a | 247 | HashTableEntry *thisNode = createHashTableEntry(key,value); //create new entry |
congvu | 3:2fe73b263a9a | 248 | |
congvu | 3:2fe73b263a9a | 249 | //Edge case to check if malloc fails in createHashTableEntry, return NULL |
congvu | 3:2fe73b263a9a | 250 | if(!thisNode) return NULL; |
congvu | 3:2fe73b263a9a | 251 | |
congvu | 3:2fe73b263a9a | 252 | /** |
congvu | 3:2fe73b263a9a | 253 | * Insert at head |
congvu | 3:2fe73b263a9a | 254 | * 1) change head of bucket to new entry |
congvu | 3:2fe73b263a9a | 255 | * 2) make new entry/head point to the changed head |
congvu | 3:2fe73b263a9a | 256 | */ |
congvu | 3:2fe73b263a9a | 257 | thisNode -> next = hashTable->buckets[bucketIndex]; |
congvu | 3:2fe73b263a9a | 258 | hashTable->buckets[bucketIndex] = thisNode; |
congvu | 3:2fe73b263a9a | 259 | return NULL; |
DCchico | 1:10330bce85cb | 260 | } |
congvu | 3:2fe73b263a9a | 261 | |
congvu | 3:2fe73b263a9a | 262 | |
DCchico | 1:10330bce85cb | 263 | void* getItem(HashTable* hashTable, unsigned int key) { |
congvu | 3:2fe73b263a9a | 264 | |
congvu | 3:2fe73b263a9a | 265 | //check if entry/node exists by calling findItem() |
congvu | 3:2fe73b263a9a | 266 | HashTableEntry* existNode = findItem(hashTable,key); |
congvu | 3:2fe73b263a9a | 267 | if(existNode) |
congvu | 3:2fe73b263a9a | 268 | { |
congvu | 3:2fe73b263a9a | 269 | return existNode -> value; |
congvu | 3:2fe73b263a9a | 270 | } |
congvu | 3:2fe73b263a9a | 271 | return NULL; |
DCchico | 1:10330bce85cb | 272 | } |
congvu | 3:2fe73b263a9a | 273 | |
DCchico | 1:10330bce85cb | 274 | void* removeItem(HashTable* hashTable, unsigned int key) { |
congvu | 3:2fe73b263a9a | 275 | |
congvu | 3:2fe73b263a9a | 276 | //get which bucket |
congvu | 3:2fe73b263a9a | 277 | int bucketIndex = hashTable -> hash(key); |
congvu | 3:2fe73b263a9a | 278 | |
congvu | 3:2fe73b263a9a | 279 | //get head of bucket |
congvu | 3:2fe73b263a9a | 280 | HashTableEntry *thisNode = hashTable -> buckets[bucketIndex]; |
congvu | 3:2fe73b263a9a | 281 | |
congvu | 3:2fe73b263a9a | 282 | //remove head |
congvu | 3:2fe73b263a9a | 283 | if(thisNode && thisNode -> key == key) |
congvu | 3:2fe73b263a9a | 284 | { |
congvu | 3:2fe73b263a9a | 285 | //get value of entry to be removed |
congvu | 3:2fe73b263a9a | 286 | void* removedEntryVal = thisNode -> value; |
congvu | 3:2fe73b263a9a | 287 | // update head |
congvu | 3:2fe73b263a9a | 288 | hashTable -> buckets[bucketIndex] = thisNode ->next; |
congvu | 3:2fe73b263a9a | 289 | //remove head entry |
congvu | 3:2fe73b263a9a | 290 | free(thisNode); |
congvu | 3:2fe73b263a9a | 291 | //return value of removed entry |
congvu | 3:2fe73b263a9a | 292 | return removedEntryVal; |
congvu | 3:2fe73b263a9a | 293 | } |
congvu | 3:2fe73b263a9a | 294 | |
congvu | 3:2fe73b263a9a | 295 | //remove node other than head |
congvu | 3:2fe73b263a9a | 296 | while(thisNode && thisNode -> next) |
congvu | 3:2fe73b263a9a | 297 | { |
congvu | 3:2fe73b263a9a | 298 | //check if next entry is one to remove |
congvu | 3:2fe73b263a9a | 299 | if(thisNode -> next -> key == key) |
congvu | 3:2fe73b263a9a | 300 | { |
congvu | 3:2fe73b263a9a | 301 | //save entry to be removed |
congvu | 3:2fe73b263a9a | 302 | HashTableEntry* entryToRemove = thisNode -> next; |
congvu | 3:2fe73b263a9a | 303 | //save value of entry to be removed |
congvu | 3:2fe73b263a9a | 304 | void* removedEntryVal = entryToRemove -> value; |
congvu | 3:2fe73b263a9a | 305 | //remove entry from list by pointing around it and freeing it |
congvu | 3:2fe73b263a9a | 306 | thisNode -> next = thisNode -> next -> next; |
congvu | 3:2fe73b263a9a | 307 | free(entryToRemove); |
congvu | 3:2fe73b263a9a | 308 | //return value of removed entry |
congvu | 3:2fe73b263a9a | 309 | return removedEntryVal; |
congvu | 3:2fe73b263a9a | 310 | } |
congvu | 3:2fe73b263a9a | 311 | //if not, get next entry |
congvu | 3:2fe73b263a9a | 312 | thisNode = thisNode -> next; |
congvu | 3:2fe73b263a9a | 313 | } |
congvu | 3:2fe73b263a9a | 314 | //if entry not in table, return NULL |
congvu | 3:2fe73b263a9a | 315 | return NULL; |
DCchico | 1:10330bce85cb | 316 | } |
congvu | 3:2fe73b263a9a | 317 | |
congvu | 3:2fe73b263a9a | 318 | |
DCchico | 1:10330bce85cb | 319 | void deleteItem(HashTable* hashTable, unsigned int key) { |
congvu | 3:2fe73b263a9a | 320 | //get which bucket |
congvu | 3:2fe73b263a9a | 321 | int bucketIndex = hashTable -> hash(key); |
congvu | 3:2fe73b263a9a | 322 | |
congvu | 3:2fe73b263a9a | 323 | //get head of bucket |
congvu | 3:2fe73b263a9a | 324 | HashTableEntry *thisNode = hashTable -> buckets[bucketIndex]; |
congvu | 3:2fe73b263a9a | 325 | if (findItem(hashTable,key) == NULL) return; |
congvu | 3:2fe73b263a9a | 326 | |
congvu | 3:2fe73b263a9a | 327 | //delete head |
congvu | 3:2fe73b263a9a | 328 | if (thisNode && thisNode ->key == key) |
congvu | 3:2fe73b263a9a | 329 | { |
congvu | 3:2fe73b263a9a | 330 | //update the head |
congvu | 3:2fe73b263a9a | 331 | hashTable -> buckets[bucketIndex] = thisNode -> next; |
congvu | 3:2fe73b263a9a | 332 | //free value of head |
congvu | 3:2fe73b263a9a | 333 | free(thisNode -> value); |
congvu | 3:2fe73b263a9a | 334 | //free head entry |
congvu | 3:2fe73b263a9a | 335 | free(thisNode); |
congvu | 3:2fe73b263a9a | 336 | return; |
congvu | 3:2fe73b263a9a | 337 | } |
congvu | 3:2fe73b263a9a | 338 | |
congvu | 3:2fe73b263a9a | 339 | //delete node other than head |
congvu | 3:2fe73b263a9a | 340 | while(thisNode && thisNode -> next) |
congvu | 3:2fe73b263a9a | 341 | { |
congvu | 3:2fe73b263a9a | 342 | //check if next entry is one to delete |
congvu | 3:2fe73b263a9a | 343 | if(thisNode -> next -> key == key) |
congvu | 3:2fe73b263a9a | 344 | { |
congvu | 3:2fe73b263a9a | 345 | //save entry to be deleted |
congvu | 3:2fe73b263a9a | 346 | HashTableEntry* entryToDelete = thisNode -> next; |
congvu | 3:2fe73b263a9a | 347 | //remove entry from list by pointing around it and freeing it |
congvu | 3:2fe73b263a9a | 348 | thisNode -> next = thisNode -> next -> next; |
congvu | 3:2fe73b263a9a | 349 | //free value |
congvu | 3:2fe73b263a9a | 350 | free(entryToDelete -> value); |
congvu | 3:2fe73b263a9a | 351 | //free entry |
congvu | 3:2fe73b263a9a | 352 | free(entryToDelete); |
congvu | 3:2fe73b263a9a | 353 | return; |
congvu | 3:2fe73b263a9a | 354 | } |
congvu | 3:2fe73b263a9a | 355 | //if not, get next entry |
congvu | 3:2fe73b263a9a | 356 | thisNode = thisNode -> next; |
congvu | 3:2fe73b263a9a | 357 | } |
congvu | 3:2fe73b263a9a | 358 | } |