#include #include #include // 定义键值对结构 typedef struct entry { void * key; // 键 void * value; // 值 struct entry * next; // 冲突链表 }*Entry; #define newEntry() NEW(struct entry) #define newEntryList(length) (Entry)malloc(length * sizeof(struct entry))\ // start HashMap结构体 // 哈希结构 typedef struct hashMap *HashMap; #define newHashMap() NEW(struct hashMap) // 哈希函数类型 typedef int(*HashCode)(HashMap, void * key); // 判等函数类型 typedef Boolean(*Equal)(void * key1, void * key2); // 添加键函数类型 typedef void(*Put)(HashMap hashMap, void * key, void * value); // 获取键对应值的函数类型 typedef void * (*Get)(HashMap hashMap, void * key); // 删除键的函数类型 typedef Boolean(*Remove)(HashMap hashMap, void * key); // 清空Map的函数类型 typedef void(*Clear)(HashMap hashMap); // 判断键值是否存在的函数类型 typedef Boolean(*Exists)(HashMap hashMap, void * key); typedef struct hashMap { int size; // 当前大小 int listSize; // 有效空间大小 HashCode hashCode; // 哈希函数 Equal equal; // 判等函数 Entry list; // 存储区域 Put put; // 添加键的函数 Get get; // 获取键对应值的函数 Remove remove; // 删除键 Clear clear; // 清空Map Exists exists; // 判断键是否存在 Boolean autoAssign; // 设定是否根据当前数据量动态调整内存大小,默认开启 }*HashMap; // // 默认哈希函数 // static int defaultHashCode(HashMap hashMap, void * key); // // 默认判断键值是否相等 // static Boolean defaultEqual(void * key1, void * key2); // // 默认添加键值对 // static void defaultPut(HashMap hashMap, void * key, void * value); // // 默认获取键对应值 // static void * defaultGet(HashMap hashMap, void * key); // // 默认删除键 // static Boolean defaultRemove(HashMap hashMap, void * key); // // 默认判断键是否存在 // static Boolean defaultExists(HashMap hashMap, void * key); // // 默认清空Map // static void defaultClear(HashMap hashMap); // // 创建一个哈希结构 // HashMap createHashMap(HashCode hashCode, Equal equal); // // 重新构建 // static void resetHashMap(HashMap hashMap, int listSize); // end HashMap结构体 // 哈希函数 int defaultHashCode(HashMap hashMap, let key) { IN_STACK; string k = (string)key; unsigned long h = 0; while (*k) { h = (h << 4) + *k++; unsigned long g = h & 0xF0000000L; if (g) { h ^= g >> 24; } h &= ~g; } OUT_STACK; return h % hashMap->listSize; } //put函数 用于在哈希表中存入一个键值对 void resetHashMap(HashMap hashMap, int listSize) { if (listSize < 8) return; // 键值对临时存储空间 Entry tempList = newEntryList(hashMap->size); HashMapIterator iterator = createHashMapIterator(hashMap); int length = hashMap->size; for (int index = 0; hasNextHashMapIterator(iterator); index++) { // 迭代取出所有键值对 iterator = nextHashMapIterator(iterator); tempList[index].key = iterator->entry->key; tempList[index].value = iterator->entry->value; tempList[index].next = NULL; } freeHashMapIterator(&iterator); // 清除原有键值对数据 hashMap->size = 0; for (int i = 0; i < hashMap->listSize; i++) { Entry current = &hashMap->list[i]; current->key = NULL; current->value = NULL; if (current->next != NULL) { while (current->next != NULL) { Entry temp = current->next->next; free(current->next); current->next = temp; } } } // 更改内存大小 hashMap->listSize = listSize; Entry relist = (Entry)realloc(hashMap->list, hashMap->listSize * sizeof(struct entry)); if (relist != NULL) { hashMap->list = relist; relist = NULL; } // 初始化数据 for (int i = 0; i < hashMap->listSize; i++) { hashMap->list[i].key = NULL; hashMap->list[i].value = NULL; hashMap->list[i].next = NULL; } // 将所有键值对重新写入内存 for (int i = 0; i < length; i++) { Array x = tempList[i].value; hashMap->put(hashMap, tempList[i].key, tempList[i].value); } free(tempList); } void defaultPut(HashMap hashMap, let key, let value) { if (hashMap->autoAssign && hashMap->size >= hashMap->listSize) { // 内存扩充至原来的两倍 // *注: 扩充时考虑的是当前存储元素数量与存储空间的大小关系,而不是存储空间是否已经存满, // 例如: 存储空间为10,存入了10个键值对,但是全部冲突了,所以存储空间空着9个,其余的全部挂在一个上面, // 这样检索的时候和遍历查询没有什么区别了,可以简单这样理解,当我存入第11个键值对的时候一定会发生冲突, // 这是由哈希函数本身的特性(取模)决定的,冲突就会导致检索变慢,所以这时候扩充存储空间,对原有键值对进行 // 再次散列,会把冲突的数据再次分散开,加快索引定位速度。 resetHashMap(hashMap, hashMap->listSize * 2); } int index = hashMap->hashCode(hashMap, key); if (hashMap->list[index].key == NULL) { hashMap->size++; // 该地址为空时直接存储 Array x = value; hashMap->list[index].key = key; hashMap->list[index].value = value; } else { Entry current = &hashMap->list[index]; while (current != NULL) { if (hashMap->equal(key, current->key)) { // 对于键值已经存在的直接覆盖 current->value = value; return; } current = current->next; }; // 发生冲突则创建节点挂到相应位置的next上 Entry entry = newEntry(); entry->key = key; entry->value = value; entry->next = hashMap->list[index].next; hashMap->list[index].next = entry; hashMap->size++; } } //其它函数 let defaultGet(HashMap hashMap, let key) { int index = hashMap->hashCode(hashMap, key); Entry entry = &hashMap->list[index]; while (entry->key != NULL && !hashMap->equal(entry->key, key)) { entry = entry->next; } return entry->value; } Boolean defaultRemove(HashMap hashMap, let key) { int index = hashMap->hashCode(hashMap, key); Entry entry = &hashMap->list[index]; if (entry->key == NULL) { return False; } Boolean result = False; if (hashMap->equal(entry->key, key)) { hashMap->size--; if (entry->next != NULL) { Entry temp = entry->next; entry->key = temp->key; entry->value = temp->value; entry->next = temp->next; free(temp); } else { entry->key = entry->value = NULL; } result = True; } else { Entry p = entry; entry = entry->next; while (entry != NULL) { if (hashMap->equal(entry->key, key)) { hashMap->size--; p->next = entry->next; free(entry); result = True; break; } p = entry; entry = entry->next; }; } // 如果空间占用不足一半,则释放多余内存 if (result && hashMap->autoAssign && hashMap->size < hashMap->listSize / 2) { resetHashMap(hashMap, hashMap->listSize / 2); } return result; } Boolean defaultExists(HashMap hashMap, let key) { int index = hashMap->hashCode(hashMap, key); Entry entry = &hashMap->list[index]; if (entry->key == NULL) { return False; } if (hashMap->equal(entry->key, key)) { return True; } if (entry->next != NULL) { do { if (hashMap->equal(entry->key, key)) { return True; } entry = entry->next; } while (entry != NULL); return False; } else { return False; } } void defaultClear(HashMap hashMap) { for (int i = 0; i < hashMap->listSize; i++) { // 释放冲突值内存 Entry entry = hashMap->list[i].next; while (entry != NULL) { Entry next = entry->next; free(entry); entry = next; } hashMap->list[i].next = NULL; } // 释放存储空间 free(hashMap->list); hashMap->list = NULL; hashMap->size = -1; hashMap->listSize = 0; } HashMap createHashMap(HashCode hashCode, Equal equal) { HashMap hashMap = newHashMap(); hashMap->size = 0; hashMap->listSize = 8; hashMap->hashCode = hashCode == NULL ? defaultHashCode : hashCode; hashMap->equal = equal == NULL ? defaultEqual : equal; hashMap->exists = defaultExists; hashMap->get = defaultGet; hashMap->put = defaultPut; hashMap->remove = defaultRemove; hashMap->clear = defaultClear; hashMap->autoAssign = True; // 起始分配8个内存空间,溢出时会自动扩充 hashMap->list = newEntryList(hashMap->listSize); Entry p = hashMap->list; for (int i = 0; i < hashMap->listSize; i++) { p[i].key = p[i].value = p[i].next = NULL; } return hashMap; } // Iterator接口提供了遍历HashMap结构的方法 // 迭代器结构 typedef struct hashMapIterator { Entry entry; // 迭代器当前指向 int count; // 迭代次数 int hashCode; // 键值对的哈希值 HashMap hashMap; }*HashMapIterator; #define newHashMapIterator() NEW(struct hashMapIterator) // // 创建一个哈希结构 // HashMap createHashMap(HashCode hashCode, Equal equal); // // 创建哈希结构迭代器 // HashMapIterator createHashMapIterator(HashMap hashMap); // // 迭代器是否有下一个 // Boolean hasNextHashMapIterator(HashMapIterator iterator); // // 迭代到下一次 // HashMapIterator nextHashMapIterator(HashMapIterator iterator); // // 释放迭代器内存 // void freeHashMapIterator(HashMapIterator * iterator); // 实现 HashMapIterator createHashMapIterator(HashMap hashMap) { HashMapIterator iterator = newHashMapIterator(); iterator->hashMap = hashMap; iterator->count = 0; iterator->hashCode = -1; iterator->entry = NULL; return iterator; } Boolean hasNextHashMapIterator(HashMapIterator iterator) { return iterator->count < iterator->hashMap->size ? True : False; } HashMapIterator nextHashMapIterator(HashMapIterator iterator) { if (hasNextHashMapIterator(iterator)) { if (iterator->entry != NULL && iterator->entry->next != NULL) { iterator->count++; iterator->entry = iterator->entry->next; return iterator; } while (++iterator->hashCode < iterator->hashMap->listSize) { Entry entry = &iterator->hashMap->list[iterator->hashCode]; if (entry->key != NULL) { iterator->count++; iterator->entry = entry; break; } } } return iterator; } void freeHashMapIterator(HashMapIterator * iterator) { free(*iterator); *iterator = NULL; } #define Put(map, key, value) map->put(map, (void *)key, (void *)value); #define Get(map, key) (char *)map->get(map, (void *)key) #define Remove(map, key) map->remove(map, (void *)key) #define Existe(map, key) map->exists(map, (void *)key) int main() { HashMap map = createHashMap(NULL, NULL); Put(map, "asdfasdf", "asdfasdfds"); Put(map, "sasdasd", "asdfasdfds"); Put(map, "asdhfgh", "asdfasdfds"); Put(map, "4545", "asdfasdfds"); Put(map, "asdfaasdasdsdf", "asdfasdfds"); Put(map, "asdasg", "asdfasdfds"); Put(map, "qweqeqwe", "asdfasdfds"); printf("key: 4545, exists: %s\n", Existe(map, "4545") ? "true" : "false"); printf("4545: %s\n", Get(map, "4545")); printf("remove 4545 %s\n", Remove(map, "4545") ? "true" : "false"); printf("remove 4545 %s\n", Remove(map, "4545") ? "true" : "false"); printf("key: 4545, exists: %s\n", Existe(map, "4545") ? "true" : "false"); HashMapIterator iterator = createHashMapIterator(map); while (hasNextHashMapIterator(iterator)) { iterator = nextHashMapIterator(iterator); printf("{ key: %s, key: %s, hashcode: %d }\n", (char *)iterator->entry->key, (char *)iterator->entry->value, iterator->hashCode); } map->clear(map); freeHashMapIterator(&iterator); return 0; }