hgftf

Dependencies:   mbed wave_player 4DGL-uLCD-SE MMA8452

Committer:
ajorgih3
Date:
Sat Apr 17 14:09:46 2021 +0000
Revision:
10:0b2f37cef9b9
Parent:
3:bb6f73642f01
huhu

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ajorgih3 3:bb6f73642f01 1 //=================================================================
DCchico 2:4947d6a82971 2 // Copyright 2020 Georgia Tech. All rights reserved.
DCchico 2:4947d6a82971 3 // The materials provided by the instructor in this course are for
DCchico 2:4947d6a82971 4 // the use of the students currently enrolled in the course.
DCchico 2:4947d6a82971 5 // Copyrighted course materials may not be further disseminated.
DCchico 2:4947d6a82971 6 // This file must not be made publicly available anywhere.
ajorgih3 3:bb6f73642f01 7 //=================================================================
ajorgih3 3:bb6f73642f01 8
DCchico 1:10330bce85cb 9 /*
ajorgih3 3:bb6f73642f01 10 Student Name: Alvin Jorgih
ajorgih3 3:bb6f73642f01 11 Date: 10/26/2020
ajorgih3 3:bb6f73642f01 12
DCchico 1:10330bce85cb 13 =======================
DCchico 1:10330bce85cb 14 ECE 2035 Project 2-1:
DCchico 1:10330bce85cb 15 =======================
DCchico 1:10330bce85cb 16 This file provides definition for the structs and functions declared in the
DCchico 1:10330bce85cb 17 header file. It also contains helper functions that are not accessible from
DCchico 1:10330bce85cb 18 outside of the file.
ajorgih3 3:bb6f73642f01 19
DCchico 1:10330bce85cb 20 FOR FULL CREDIT, BE SURE TO TRY MULTIPLE TEST CASES and DOCUMENT YOUR CODE.
ajorgih3 3:bb6f73642f01 21
DCchico 1:10330bce85cb 22 ===================================
DCchico 1:10330bce85cb 23 Naming conventions in this file:
DCchico 1:10330bce85cb 24 ===================================
DCchico 1:10330bce85cb 25 1. All struct names use camel case where the first letter is capitalized.
DCchico 1:10330bce85cb 26 e.g. "HashTable", or "HashTableEntry"
ajorgih3 3:bb6f73642f01 27
DCchico 1:10330bce85cb 28 2. Variable names with a preceding underscore "_" will not be called directly.
DCchico 1:10330bce85cb 29 e.g. "_HashTable", "_HashTableEntry"
ajorgih3 3:bb6f73642f01 30
DCchico 1:10330bce85cb 31 Recall that in C, we have to type "struct" together with the name of the struct
DCchico 1:10330bce85cb 32 in order to initialize a new variable. To avoid this, in hash_table.h
DCchico 1:10330bce85cb 33 we use typedef to provide new "nicknames" for "struct _HashTable" and
DCchico 1:10330bce85cb 34 "struct _HashTableEntry". As a result, we can create new struct variables
DCchico 1:10330bce85cb 35 by just using:
DCchico 1:10330bce85cb 36 - "HashTable myNewTable;"
DCchico 1:10330bce85cb 37 or
DCchico 1:10330bce85cb 38 - "HashTableEntry myNewHashTableEntry;"
ajorgih3 3:bb6f73642f01 39
DCchico 1:10330bce85cb 40 The preceding underscore "_" simply provides a distinction between the names
DCchico 1:10330bce85cb 41 of the actual struct defition and the "nicknames" that we use to initialize
DCchico 1:10330bce85cb 42 new structs.
DCchico 1:10330bce85cb 43 [See Hidden Definitions section for more information.]
ajorgih3 3:bb6f73642f01 44
DCchico 1:10330bce85cb 45 3. Functions, their local variables and arguments are named with camel case, where
DCchico 1:10330bce85cb 46 the first letter is lower-case.
DCchico 1:10330bce85cb 47 e.g. "createHashTable" is a function. One of its arguments is "numBuckets".
DCchico 1:10330bce85cb 48 It also has a local variable called "newTable".
ajorgih3 3:bb6f73642f01 49
DCchico 1:10330bce85cb 50 4. The name of a struct member is divided by using underscores "_". This serves
DCchico 1:10330bce85cb 51 as a distinction between function local variables and struct members.
DCchico 1:10330bce85cb 52 e.g. "num_buckets" is a member of "HashTable".
ajorgih3 3:bb6f73642f01 53
DCchico 1:10330bce85cb 54 */
ajorgih3 3:bb6f73642f01 55
DCchico 1:10330bce85cb 56 /****************************************************************************
DCchico 1:10330bce85cb 57 * Include the Public Interface
DCchico 1:10330bce85cb 58 *
DCchico 1:10330bce85cb 59 * By including the public interface at the top of the file, the compiler can
DCchico 1:10330bce85cb 60 * enforce that the function declarations in the the header are not in
DCchico 1:10330bce85cb 61 * conflict with the definitions in the file. This is not a guarantee of
DCchico 1:10330bce85cb 62 * correctness, but it is better than nothing!
DCchico 1:10330bce85cb 63 ***************************************************************************/
DCchico 1:10330bce85cb 64 #include "hash_table.h"
ajorgih3 3:bb6f73642f01 65
DCchico 1:10330bce85cb 66 /****************************************************************************
DCchico 1:10330bce85cb 67 * Include other private dependencies
DCchico 1:10330bce85cb 68 *
DCchico 1:10330bce85cb 69 * These other modules are used in the implementation of the hash table module,
DCchico 1:10330bce85cb 70 * but are not required by users of the hash table.
DCchico 1:10330bce85cb 71 ***************************************************************************/
ajorgih3 3:bb6f73642f01 72 #include <stdlib.h> // For malloc and free
ajorgih3 3:bb6f73642f01 73 #include <stdio.h> // For printf
ajorgih3 3:bb6f73642f01 74
DCchico 1:10330bce85cb 75 /****************************************************************************
DCchico 1:10330bce85cb 76 * Hidden Definitions
DCchico 1:10330bce85cb 77 *
DCchico 1:10330bce85cb 78 * These definitions are not available outside of this file. However, because
DCchico 1:10330bce85cb 79 * the are forward declared in hash_table.h, the type names are
DCchico 1:10330bce85cb 80 * available everywhere and user code can hold pointers to these structs.
DCchico 1:10330bce85cb 81 ***************************************************************************/
DCchico 1:10330bce85cb 82 /**
DCchico 1:10330bce85cb 83 * This structure represents an a hash table.
DCchico 1:10330bce85cb 84 * Use "HashTable" instead when you are creating a new variable. [See top comments]
DCchico 1:10330bce85cb 85 */
ajorgih3 3:bb6f73642f01 86 struct _HashTable
ajorgih3 3:bb6f73642f01 87 {
DCchico 1:10330bce85cb 88 /** The array of pointers to the head of a singly linked list, whose nodes
DCchico 1:10330bce85cb 89 are HashTableEntry objects */
ajorgih3 3:bb6f73642f01 90 HashTableEntry **buckets;
ajorgih3 3:bb6f73642f01 91
DCchico 1:10330bce85cb 92 /** The hash function pointer */
DCchico 1:10330bce85cb 93 HashFunction hash;
ajorgih3 3:bb6f73642f01 94
DCchico 1:10330bce85cb 95 /** The number of buckets in the hash table */
DCchico 1:10330bce85cb 96 unsigned int num_buckets;
DCchico 1:10330bce85cb 97 };
ajorgih3 3:bb6f73642f01 98
DCchico 1:10330bce85cb 99 /**
DCchico 1:10330bce85cb 100 * This structure represents a hash table entry.
DCchico 1:10330bce85cb 101 * Use "HashTableEntry" instead when you are creating a new variable. [See top comments]
DCchico 1:10330bce85cb 102 */
ajorgih3 3:bb6f73642f01 103 struct _HashTableEntry
ajorgih3 3:bb6f73642f01 104 {
DCchico 1:10330bce85cb 105 /** The key for the hash table entry */
DCchico 1:10330bce85cb 106 unsigned int key;
ajorgih3 3:bb6f73642f01 107
DCchico 1:10330bce85cb 108 /** The value associated with this hash table entry */
ajorgih3 3:bb6f73642f01 109 void *value;
ajorgih3 3:bb6f73642f01 110
DCchico 1:10330bce85cb 111 /**
DCchico 1:10330bce85cb 112 * A pointer pointing to the next hash table entry
DCchico 1:10330bce85cb 113 * NULL means there is no next entry (i.e. this is the tail)
DCchico 1:10330bce85cb 114 */
ajorgih3 3:bb6f73642f01 115 HashTableEntry *next;
DCchico 1:10330bce85cb 116 };
ajorgih3 3:bb6f73642f01 117
DCchico 1:10330bce85cb 118 /****************************************************************************
DCchico 1:10330bce85cb 119 * Private Functions
DCchico 1:10330bce85cb 120 *
DCchico 1:10330bce85cb 121 * These functions are not available outside of this file, since they are not
DCchico 1:10330bce85cb 122 * declared in hash_table.h.
DCchico 1:10330bce85cb 123 ***************************************************************************/
DCchico 1:10330bce85cb 124 /**
DCchico 1:10330bce85cb 125 * createHashTableEntry
DCchico 1:10330bce85cb 126 *
DCchico 1:10330bce85cb 127 * Helper function that creates a hash table entry by allocating memory for it on
DCchico 1:10330bce85cb 128 * the heap. It initializes the entry with key and value, initialize pointer to
DCchico 1:10330bce85cb 129 * the next entry as NULL, and return the pointer to this hash table entry.
DCchico 1:10330bce85cb 130 *
DCchico 1:10330bce85cb 131 * @param key The key corresponds to the hash table entry
DCchico 1:10330bce85cb 132 * @param value The value stored in the hash table entry
DCchico 1:10330bce85cb 133 * @return The pointer to the hash table entry
DCchico 1:10330bce85cb 134 */
ajorgih3 3:bb6f73642f01 135 static HashTableEntry *createHashTableEntry(unsigned int key, void *value)
ajorgih3 3:bb6f73642f01 136 {
ajorgih3 3:bb6f73642f01 137 // init hash table entry by allocating memory for it on the heap
ajorgih3 3:bb6f73642f01 138 HashTableEntry *newEntry = (HashTableEntry *)malloc(sizeof(HashTableEntry));
ajorgih3 3:bb6f73642f01 139 // init the key on the key field in the entry
ajorgih3 3:bb6f73642f01 140 newEntry->key = key;
ajorgih3 3:bb6f73642f01 141 // init the value on the value field in the entry
ajorgih3 3:bb6f73642f01 142 newEntry->value = value;
ajorgih3 3:bb6f73642f01 143 // init the value on the next field in the entry
ajorgih3 3:bb6f73642f01 144 newEntry->next = NULL;
ajorgih3 3:bb6f73642f01 145 // return to the hash table of the entry
ajorgih3 3:bb6f73642f01 146 return newEntry;
DCchico 1:10330bce85cb 147 }
ajorgih3 3:bb6f73642f01 148
DCchico 1:10330bce85cb 149 /**
DCchico 1:10330bce85cb 150 * findItem
DCchico 1:10330bce85cb 151 *
DCchico 1:10330bce85cb 152 * Helper function that checks whether there exists the hash table entry that
DCchico 1:10330bce85cb 153 * contains a specific key.
DCchico 1:10330bce85cb 154 *
DCchico 1:10330bce85cb 155 * @param hashTable The pointer to the hash table.
DCchico 1:10330bce85cb 156 * @param key The key corresponds to the hash table entry
DCchico 1:10330bce85cb 157 * @return The pointer to the hash table entry, or NULL if key does not exist
DCchico 1:10330bce85cb 158 */
ajorgih3 3:bb6f73642f01 159 static HashTableEntry *findItem(HashTable *hashTable, unsigned int key)
ajorgih3 3:bb6f73642f01 160 {
ajorgih3 3:bb6f73642f01 161 // initialize bucket key
ajorgih3 3:bb6f73642f01 162 unsigned int bucketKey;
ajorgih3 3:bb6f73642f01 163 // get the bucketkey by hashing the key and dereferencing the value
ajorgih3 3:bb6f73642f01 164 bucketKey = hashTable->hash(key);
ajorgih3 3:bb6f73642f01 165 // pointer to the bucket head, the first item in the bucket with
ajorgih3 3:bb6f73642f01 166 // the corresponding input key
ajorgih3 3:bb6f73642f01 167 HashTableEntry *bucketHead = hashTable->buckets[bucketKey];
ajorgih3 3:bb6f73642f01 168
ajorgih3 3:bb6f73642f01 169 // edge case where there is nothing inside the bucket
ajorgih3 3:bb6f73642f01 170 if (bucketHead == NULL) {
ajorgih3 3:bb6f73642f01 171 return NULL;
ajorgih3 3:bb6f73642f01 172 }
ajorgih3 3:bb6f73642f01 173
ajorgih3 3:bb6f73642f01 174 // else if bucket is not NULL
ajorgih3 3:bb6f73642f01 175 if (bucketHead != NULL)
ajorgih3 3:bb6f73642f01 176 {
ajorgih3 3:bb6f73642f01 177 // we loop through the items
ajorgih3 3:bb6f73642f01 178 while (bucketHead != NULL)
ajorgih3 3:bb6f73642f01 179 {
ajorgih3 3:bb6f73642f01 180 // and if the key of one of the items matches with a key
ajorgih3 3:bb6f73642f01 181 if (bucketHead->key == key)
ajorgih3 3:bb6f73642f01 182 {
ajorgih3 3:bb6f73642f01 183 // return the following item
ajorgih3 3:bb6f73642f01 184 return bucketHead;
ajorgih3 3:bb6f73642f01 185 }
ajorgih3 3:bb6f73642f01 186 else
ajorgih3 3:bb6f73642f01 187 {
ajorgih3 3:bb6f73642f01 188 // else we continue traversing
ajorgih3 3:bb6f73642f01 189 bucketHead = bucketHead->next;
ajorgih3 3:bb6f73642f01 190 }
ajorgih3 3:bb6f73642f01 191 }
ajorgih3 3:bb6f73642f01 192 }
ajorgih3 3:bb6f73642f01 193 return NULL;
DCchico 1:10330bce85cb 194 }
ajorgih3 3:bb6f73642f01 195
DCchico 1:10330bce85cb 196 /****************************************************************************
DCchico 1:10330bce85cb 197 * Public Interface Functions
DCchico 1:10330bce85cb 198 *
DCchico 1:10330bce85cb 199 * These functions implement the public interface as specified in the header
DCchico 1:10330bce85cb 200 * file, and make use of the private functions and hidden definitions in the
DCchico 1:10330bce85cb 201 * above sections.
DCchico 1:10330bce85cb 202 ****************************************************************************/
DCchico 1:10330bce85cb 203 // The createHashTable is provided for you as a starting point.
ajorgih3 3:bb6f73642f01 204 HashTable *createHashTable(HashFunction hashFunction, unsigned int numBuckets)
ajorgih3 3:bb6f73642f01 205 {
DCchico 1:10330bce85cb 206 // The hash table has to contain at least one bucket. Exit gracefully if
DCchico 1:10330bce85cb 207 // this condition is not met.
ajorgih3 3:bb6f73642f01 208 if (numBuckets == 0)
ajorgih3 3:bb6f73642f01 209 {
DCchico 1:10330bce85cb 210 printf("Hash table has to contain at least 1 bucket...\n");
DCchico 1:10330bce85cb 211 exit(1);
DCchico 1:10330bce85cb 212 }
ajorgih3 3:bb6f73642f01 213
DCchico 1:10330bce85cb 214 // Allocate memory for the new HashTable struct on heap.
ajorgih3 3:bb6f73642f01 215 // size of HashTable: determined by the type of the HashTable
ajorgih3 3:bb6f73642f01 216 // malloc: allocates size for the HashTable
ajorgih3 3:bb6f73642f01 217 HashTable *newTable = (HashTable *)malloc(sizeof(HashTable));
ajorgih3 3:bb6f73642f01 218
DCchico 1:10330bce85cb 219 // Initialize the components of the new HashTable struct.
ajorgih3 3:bb6f73642f01 220 // new table assigning value to hash
ajorgih3 3:bb6f73642f01 221 // new table assigning value to num_buckets
ajorgih3 3:bb6f73642f01 222 // new table assigning value to buckets
DCchico 1:10330bce85cb 223 newTable->hash = hashFunction;
DCchico 1:10330bce85cb 224 newTable->num_buckets = numBuckets;
ajorgih3 3:bb6f73642f01 225 newTable->buckets = (HashTableEntry **)malloc(numBuckets * sizeof(HashTableEntry *));
ajorgih3 3:bb6f73642f01 226
ajorgih3 3:bb6f73642f01 227 // As the new buckets contain indeterminant values, init each bucket as NULL.
DCchico 1:10330bce85cb 228 unsigned int i;
ajorgih3 3:bb6f73642f01 229 for (i = 0; i < numBuckets; ++i)
ajorgih3 3:bb6f73642f01 230 {
DCchico 1:10330bce85cb 231 newTable->buckets[i] = NULL;
DCchico 1:10330bce85cb 232 }
ajorgih3 3:bb6f73642f01 233
DCchico 1:10330bce85cb 234 // Return the new HashTable struct.
DCchico 1:10330bce85cb 235 return newTable;
DCchico 1:10330bce85cb 236 }
ajorgih3 3:bb6f73642f01 237
ajorgih3 3:bb6f73642f01 238 /**
ajorgih3 3:bb6f73642f01 239 * destroyHashTable
ajorgih3 3:bb6f73642f01 240 *
ajorgih3 3:bb6f73642f01 241 * Destroy the hash table. The nodes (HashTableEntry objects) of singly linked
ajorgih3 3:bb6f73642f01 242 * list, the values stored on the linked list, the buckets, and the hashtable
ajorgih3 3:bb6f73642f01 243 * itself are freed from the heap. In other words, free all the allocated memory
ajorgih3 3:bb6f73642f01 244 * on heap that is associated with heap, including the values that users store in
ajorgih3 3:bb6f73642f01 245 * the hash table.
ajorgih3 3:bb6f73642f01 246 *
ajorgih3 3:bb6f73642f01 247 */
ajorgih3 3:bb6f73642f01 248 //need to ask Dr. Wills about this
ajorgih3 3:bb6f73642f01 249 void destroyHashTable(HashTable *hashTable)
ajorgih3 3:bb6f73642f01 250 {
ajorgih3 3:bb6f73642f01 251 // iterate through each buckets, condition the number of buckets
ajorgih3 3:bb6f73642f01 252 // if it is NULL, means no head, thus continue iteration
ajorgih3 3:bb6f73642f01 253 // no direct access to num buckets, thus we use pointer to num buckets
ajorgih3 3:bb6f73642f01 254 unsigned int i;
ajorgih3 3:bb6f73642f01 255 // for loop to traverse through the hash table buckets
ajorgih3 3:bb6f73642f01 256 for (i = 0; i < (hashTable->num_buckets); ++i)
ajorgih3 3:bb6f73642f01 257 {
ajorgih3 3:bb6f73642f01 258 //points to the value preceding the next one, for memory purposes
ajorgih3 3:bb6f73642f01 259 HashTableEntry *pointer1 = hashTable->buckets[i];
ajorgih3 3:bb6f73642f01 260 // if pointer1 is NULL, pointer 2 then will create SegFault
ajorgih3 3:bb6f73642f01 261 if (pointer1 != NULL)
ajorgih3 3:bb6f73642f01 262 {
ajorgih3 3:bb6f73642f01 263 // pointer2 if they have a value for pointer 1
ajorgih3 3:bb6f73642f01 264 HashTableEntry *pointer2 = pointer1->next;
ajorgih3 3:bb6f73642f01 265 // while pointer2 is not NULL
ajorgih3 3:bb6f73642f01 266 while (pointer2 != NULL)
ajorgih3 3:bb6f73642f01 267 {
ajorgih3 3:bb6f73642f01 268 // free the value of pointer1
ajorgih3 3:bb6f73642f01 269 free(pointer1->value);
ajorgih3 3:bb6f73642f01 270 // free the entry of pointer1
ajorgih3 3:bb6f73642f01 271 free(pointer1);
ajorgih3 3:bb6f73642f01 272 // pointer1 moves to pointer 2
ajorgih3 3:bb6f73642f01 273 pointer1 = pointer2;
ajorgih3 3:bb6f73642f01 274 // pointer 2 moves to the next after pointer 2
ajorgih3 3:bb6f73642f01 275 pointer2 = pointer2->next;
ajorgih3 3:bb6f73642f01 276 }
ajorgih3 3:bb6f73642f01 277 // free the last value of the pointer
ajorgih3 3:bb6f73642f01 278 free(pointer1->value);
ajorgih3 3:bb6f73642f01 279 // free the pointer itself
ajorgih3 3:bb6f73642f01 280 free(pointer1);
ajorgih3 3:bb6f73642f01 281 }
ajorgih3 3:bb6f73642f01 282 }
ajorgih3 3:bb6f73642f01 283
ajorgih3 3:bb6f73642f01 284 // if everything is done, we free up the hashTable
ajorgih3 3:bb6f73642f01 285 free(hashTable->buckets);
ajorgih3 3:bb6f73642f01 286 // free the hashtable
ajorgih3 3:bb6f73642f01 287 free(hashTable);
ajorgih3 3:bb6f73642f01 288 // return
ajorgih3 3:bb6f73642f01 289 return;
DCchico 1:10330bce85cb 290 }
ajorgih3 3:bb6f73642f01 291
ajorgih3 3:bb6f73642f01 292 /**
ajorgih3 3:bb6f73642f01 293 * insertItem
ajorgih3 3:bb6f73642f01 294 *
ajorgih3 3:bb6f73642f01 295 * Insert the value into the hash table based on the key.
ajorgih3 3:bb6f73642f01 296 * In other words, create a new hash table entry and add it to a specific bucket.
ajorgih3 3:bb6f73642f01 297 *
ajorgih3 3:bb6f73642f01 298 */
ajorgih3 3:bb6f73642f01 299 void *insertItem(HashTable *hashTable, unsigned int key, void *value)
ajorgih3 3:bb6f73642f01 300 {
ajorgih3 3:bb6f73642f01 301 // init index after hashing
ajorgih3 3:bb6f73642f01 302 unsigned int bucketHashIndex = hashTable->hash(key);
ajorgih3 3:bb6f73642f01 303 //init a pointer to the head of the bucket
ajorgih3 3:bb6f73642f01 304 HashTableEntry *bucketHead = hashTable->buckets[bucketHashIndex];
ajorgih3 3:bb6f73642f01 305
ajorgih3 3:bb6f73642f01 306 // while bucket head is not null
ajorgih3 3:bb6f73642f01 307 while (bucketHead != NULL)
ajorgih3 3:bb6f73642f01 308 {
ajorgih3 3:bb6f73642f01 309 //if the bucket head has the same value like the key
ajorgih3 3:bb6f73642f01 310 if (bucketHead->key == key)
ajorgih3 3:bb6f73642f01 311 {
ajorgih3 3:bb6f73642f01 312 // store the old value of the key to be returned
ajorgih3 3:bb6f73642f01 313 void *oldValue = bucketHead->value;
ajorgih3 3:bb6f73642f01 314 // change the bucket head value
ajorgih3 3:bb6f73642f01 315 bucketHead->value = value;
ajorgih3 3:bb6f73642f01 316 //return to the old value
ajorgih3 3:bb6f73642f01 317 return oldValue;
ajorgih3 3:bb6f73642f01 318 }
ajorgih3 3:bb6f73642f01 319
ajorgih3 3:bb6f73642f01 320 // else keep traversing
ajorgih3 3:bb6f73642f01 321 else
ajorgih3 3:bb6f73642f01 322 {
ajorgih3 3:bb6f73642f01 323 // reaching the last entry in the bucket
ajorgih3 3:bb6f73642f01 324 bucketHead = bucketHead->next;
ajorgih3 3:bb6f73642f01 325 }
ajorgih3 3:bb6f73642f01 326 }
ajorgih3 3:bb6f73642f01 327
ajorgih3 3:bb6f73642f01 328 // init new entry, should be here just because, if this is declared at the top
ajorgih3 3:bb6f73642f01 329 // it will cause a memory leak due to the fact it may become unused
ajorgih3 3:bb6f73642f01 330 HashTableEntry *newEntry = createHashTableEntry(key, value);
ajorgih3 3:bb6f73642f01 331
ajorgih3 3:bb6f73642f01 332 // we are adding the entry from the front
ajorgih3 3:bb6f73642f01 333 newEntry->next = hashTable->buckets[bucketHashIndex];
ajorgih3 3:bb6f73642f01 334 hashTable->buckets[bucketHashIndex] = newEntry;
ajorgih3 3:bb6f73642f01 335
ajorgih3 3:bb6f73642f01 336 return NULL;
ajorgih3 3:bb6f73642f01 337 }
ajorgih3 3:bb6f73642f01 338
ajorgih3 3:bb6f73642f01 339 /**
ajorgih3 3:bb6f73642f01 340 * getItem
ajorgih3 3:bb6f73642f01 341 *
ajorgih3 3:bb6f73642f01 342 * Get the value that corresponds to the key in the hash table.
ajorgih3 3:bb6f73642f01 343 *
ajorgih3 3:bb6f73642f01 344 */
ajorgih3 3:bb6f73642f01 345 // get item utilizes the static function from findItem
ajorgih3 3:bb6f73642f01 346 void *getItem(HashTable *hashTable, unsigned int key)
ajorgih3 3:bb6f73642f01 347 {
ajorgih3 3:bb6f73642f01 348 // call findItem and set it as a variable
ajorgih3 3:bb6f73642f01 349 HashTableEntry *item = findItem(hashTable, key);
ajorgih3 3:bb6f73642f01 350 // if it is not NULL, then we make another pointer to the value of the variable
ajorgih3 3:bb6f73642f01 351 if (item != NULL)
ajorgih3 3:bb6f73642f01 352 {
ajorgih3 3:bb6f73642f01 353 // return the value of the item
ajorgih3 3:bb6f73642f01 354 return item->value;
ajorgih3 3:bb6f73642f01 355 }
ajorgih3 3:bb6f73642f01 356
ajorgih3 3:bb6f73642f01 357 // else return NULL
ajorgih3 3:bb6f73642f01 358 return NULL;
DCchico 1:10330bce85cb 359 }
ajorgih3 3:bb6f73642f01 360
ajorgih3 3:bb6f73642f01 361 /**
ajorgih3 3:bb6f73642f01 362 * removeItem
ajorgih3 3:bb6f73642f01 363 *
ajorgih3 3:bb6f73642f01 364 * Remove the item in hash table based on the key and return the value stored in it.
ajorgih3 3:bb6f73642f01 365 * In other words, return the value and free the hash table entry from heap.
ajorgih3 3:bb6f73642f01 366 *
ajorgih3 3:bb6f73642f01 367 */
ajorgih3 3:bb6f73642f01 368 void *removeItem(HashTable *hashTable, unsigned int key)
ajorgih3 3:bb6f73642f01 369 {
ajorgih3 3:bb6f73642f01 370
ajorgih3 3:bb6f73642f01 371 // we need to consider three cases: when the entry is on the head of the node
ajorgih3 3:bb6f73642f01 372 // when the entry is sandwiched between two nodes
ajorgih3 3:bb6f73642f01 373 // when the entry is at the end of the node
ajorgih3 3:bb6f73642f01 374 // when the entry is not found
ajorgih3 3:bb6f73642f01 375
ajorgih3 3:bb6f73642f01 376 int bucketKey = hashTable->hash(key);
ajorgih3 3:bb6f73642f01 377 HashTableEntry *pointer1 = hashTable->buckets[bucketKey];
ajorgih3 3:bb6f73642f01 378
ajorgih3 3:bb6f73642f01 379 // if the list is empty
ajorgih3 3:bb6f73642f01 380 if (pointer1 == NULL) {
ajorgih3 3:bb6f73642f01 381 return NULL;
ajorgih3 3:bb6f73642f01 382 }
ajorgih3 3:bb6f73642f01 383
ajorgih3 3:bb6f73642f01 384 // if the entry is not null
ajorgih3 3:bb6f73642f01 385 if (pointer1 != NULL)
ajorgih3 3:bb6f73642f01 386 {
ajorgih3 3:bb6f73642f01 387 HashTableEntry *pointer2 = pointer1->next;
ajorgih3 3:bb6f73642f01 388 // if the value of the key is in on the head of the node
ajorgih3 3:bb6f73642f01 389 if (pointer1->key == key)
ajorgih3 3:bb6f73642f01 390 {
ajorgih3 3:bb6f73642f01 391 // deleted value saved to a variable called deleted value
ajorgih3 3:bb6f73642f01 392 void *deletedValue = pointer1->value;
ajorgih3 3:bb6f73642f01 393 // free the entry
ajorgih3 3:bb6f73642f01 394 free(pointer1);
ajorgih3 3:bb6f73642f01 395 // connects the head to the next pointer
ajorgih3 3:bb6f73642f01 396 hashTable->buckets[bucketKey] = pointer2;
ajorgih3 3:bb6f73642f01 397 // returns deleted value
ajorgih3 3:bb6f73642f01 398 return deletedValue;
ajorgih3 3:bb6f73642f01 399 }
ajorgih3 3:bb6f73642f01 400
ajorgih3 3:bb6f73642f01 401 // when the entry is in the middle or at the end
ajorgih3 3:bb6f73642f01 402 else
ajorgih3 3:bb6f73642f01 403 {
ajorgih3 3:bb6f73642f01 404 while (pointer2 != NULL)
ajorgih3 3:bb6f73642f01 405 {
ajorgih3 3:bb6f73642f01 406 if (pointer2->key == key)
ajorgih3 3:bb6f73642f01 407 {
ajorgih3 3:bb6f73642f01 408 // points to the deleted value
ajorgih3 3:bb6f73642f01 409 void *deletedValue = pointer2->value;
ajorgih3 3:bb6f73642f01 410
ajorgih3 3:bb6f73642f01 411 // if the key is in the last place
ajorgih3 3:bb6f73642f01 412 if (pointer2->next == NULL)
ajorgih3 3:bb6f73642f01 413 {
ajorgih3 3:bb6f73642f01 414 // pointer points to NULL
ajorgih3 3:bb6f73642f01 415 pointer1->next = NULL;
ajorgih3 3:bb6f73642f01 416 }
ajorgih3 3:bb6f73642f01 417
ajorgih3 3:bb6f73642f01 418 // if the entry is in the middle
ajorgih3 3:bb6f73642f01 419 else
ajorgih3 3:bb6f73642f01 420 {
ajorgih3 3:bb6f73642f01 421 pointer1->next = pointer2->next;
ajorgih3 3:bb6f73642f01 422 }
ajorgih3 3:bb6f73642f01 423 // free the value of the second pointer
ajorgih3 3:bb6f73642f01 424 free(pointer2);
ajorgih3 3:bb6f73642f01 425 // return deleted value
ajorgih3 3:bb6f73642f01 426 return deletedValue;
ajorgih3 3:bb6f73642f01 427 }
ajorgih3 3:bb6f73642f01 428
ajorgih3 3:bb6f73642f01 429 // else pointer next
ajorgih3 3:bb6f73642f01 430 else
ajorgih3 3:bb6f73642f01 431 {
ajorgih3 3:bb6f73642f01 432 // pointer 1 is now pointer 2
ajorgih3 3:bb6f73642f01 433 pointer1 = pointer2;
ajorgih3 3:bb6f73642f01 434 // pointer 2 is now the next value of its first value
ajorgih3 3:bb6f73642f01 435 pointer2 = pointer2->next;
ajorgih3 3:bb6f73642f01 436 }
ajorgih3 3:bb6f73642f01 437 }
ajorgih3 3:bb6f73642f01 438 }
ajorgih3 3:bb6f73642f01 439 }
ajorgih3 3:bb6f73642f01 440
ajorgih3 3:bb6f73642f01 441 // else return NULL
ajorgih3 3:bb6f73642f01 442 return NULL;
DCchico 1:10330bce85cb 443 }
ajorgih3 3:bb6f73642f01 444
ajorgih3 3:bb6f73642f01 445 /**
ajorgih3 3:bb6f73642f01 446 * deleteItem
ajorgih3 3:bb6f73642f01 447 *
ajorgih3 3:bb6f73642f01 448 * Delete the item in the hash table based on the key. In other words, free the
ajorgih3 3:bb6f73642f01 449 * value stored in the hash table entry and the hash table entry itself from
ajorgih3 3:bb6f73642f01 450 * the heap.
ajorgih3 3:bb6f73642f01 451 *
ajorgih3 3:bb6f73642f01 452 */
ajorgih3 3:bb6f73642f01 453 void deleteItem(HashTable *hashTable, unsigned int key)
ajorgih3 3:bb6f73642f01 454 {
ajorgih3 3:bb6f73642f01 455
ajorgih3 3:bb6f73642f01 456 // we need to consider three cases: when the entry is on the head of the node
ajorgih3 3:bb6f73642f01 457 // when the entry is sandwiched between two nodes
ajorgih3 3:bb6f73642f01 458 // when the entry is at the end of the node
ajorgih3 3:bb6f73642f01 459 // when the entry is not found
ajorgih3 3:bb6f73642f01 460
ajorgih3 3:bb6f73642f01 461 int bucketKey = hashTable->hash(key);
ajorgih3 3:bb6f73642f01 462 HashTableEntry *pointer1 = hashTable->buckets[bucketKey];
ajorgih3 3:bb6f73642f01 463
ajorgih3 3:bb6f73642f01 464 // if the list is empty
ajorgih3 3:bb6f73642f01 465 if (pointer1 == NULL) {
ajorgih3 3:bb6f73642f01 466 return;
ajorgih3 3:bb6f73642f01 467 }
ajorgih3 3:bb6f73642f01 468
ajorgih3 3:bb6f73642f01 469 // if the entry is not null
ajorgih3 3:bb6f73642f01 470 if (pointer1 != NULL)
ajorgih3 3:bb6f73642f01 471 {
ajorgih3 3:bb6f73642f01 472 HashTableEntry *pointer2 = pointer1->next;
ajorgih3 3:bb6f73642f01 473 // if the value of the key is in on the head of the node
ajorgih3 3:bb6f73642f01 474 if (pointer1->key == key)
ajorgih3 3:bb6f73642f01 475 {
ajorgih3 3:bb6f73642f01 476 // free the value of the pointer
ajorgih3 3:bb6f73642f01 477 free(pointer1->value);
ajorgih3 3:bb6f73642f01 478 pointer1->value = NULL;
ajorgih3 3:bb6f73642f01 479 // free the entry
ajorgih3 3:bb6f73642f01 480 free(pointer1);
ajorgih3 3:bb6f73642f01 481 // connects the head to the next pointer
ajorgih3 3:bb6f73642f01 482 hashTable->buckets[bucketKey] = pointer2;
ajorgih3 3:bb6f73642f01 483 // returns deleted value
ajorgih3 3:bb6f73642f01 484 return;
ajorgih3 3:bb6f73642f01 485 }
ajorgih3 3:bb6f73642f01 486
ajorgih3 3:bb6f73642f01 487 // when the entry is in the middle or at the end
ajorgih3 3:bb6f73642f01 488 else
ajorgih3 3:bb6f73642f01 489 {
ajorgih3 3:bb6f73642f01 490 while (pointer2 != NULL)
ajorgih3 3:bb6f73642f01 491 {
ajorgih3 3:bb6f73642f01 492 if (pointer2->key == key)
ajorgih3 3:bb6f73642f01 493 {
ajorgih3 3:bb6f73642f01 494 // if the key is in the last place
ajorgih3 3:bb6f73642f01 495 if (pointer2->next == NULL)
ajorgih3 3:bb6f73642f01 496 {
ajorgih3 3:bb6f73642f01 497 // pointer points to NULL
ajorgih3 3:bb6f73642f01 498 pointer1->next = NULL;
ajorgih3 3:bb6f73642f01 499 }
ajorgih3 3:bb6f73642f01 500
ajorgih3 3:bb6f73642f01 501 // if the entry is in the middle
ajorgih3 3:bb6f73642f01 502 else
ajorgih3 3:bb6f73642f01 503 {
ajorgih3 3:bb6f73642f01 504 pointer1->next = pointer2->next;
ajorgih3 3:bb6f73642f01 505 }
ajorgih3 3:bb6f73642f01 506 // free the value of the pointer
ajorgih3 3:bb6f73642f01 507 free(pointer2->value);
ajorgih3 3:bb6f73642f01 508 // free the value of the second pointer
ajorgih3 3:bb6f73642f01 509 free(pointer2);
ajorgih3 3:bb6f73642f01 510 // return deleted value
ajorgih3 3:bb6f73642f01 511 return;
ajorgih3 3:bb6f73642f01 512 }
ajorgih3 3:bb6f73642f01 513
ajorgih3 3:bb6f73642f01 514 // else pointer next
ajorgih3 3:bb6f73642f01 515 else
ajorgih3 3:bb6f73642f01 516 {
ajorgih3 3:bb6f73642f01 517 // pointer 1 is now pointer 2
ajorgih3 3:bb6f73642f01 518 pointer1 = pointer2;
ajorgih3 3:bb6f73642f01 519 // pointer 2 is now the next value of its first value
ajorgih3 3:bb6f73642f01 520 pointer2 = pointer2->next;
ajorgih3 3:bb6f73642f01 521 }
ajorgih3 3:bb6f73642f01 522 }
ajorgih3 3:bb6f73642f01 523 }
ajorgih3 3:bb6f73642f01 524 }
ajorgih3 3:bb6f73642f01 525
ajorgih3 3:bb6f73642f01 526 // else return if the value is not in the hash table
ajorgih3 3:bb6f73642f01 527 return;
DCchico 1:10330bce85cb 528 }