diff --git a/APP_Framework/Applications/app_test/test_hash/test_hash.c b/APP_Framework/Applications/app_test/test_hash/test_hash.c index d6eabc4c7..6e91f621b 100644 --- a/APP_Framework/Applications/app_test/test_hash/test_hash.c +++ b/APP_Framework/Applications/app_test/test_hash/test_hash.c @@ -1,31 +1,49 @@ -/** -* @file: test_hash.c -* @brief: a application of test hash function -* @version: 3.0 -* @author: Yao wenying -* @date: 2023/05/26 -*/ - #include #include"test_hash.h" -int defaultHashCode(HashMap hashMap, let key) { - char * k = (char *)key; - unsigned long h = 0; - while (*k) { - h = (h << 4) + *k++; - unsigned long g = h & 0xF0000000L; - if (g) { - h ^= g >> 24; - } - h &= ~g; - } - return h % hashMap->listSize; +// 默认哈希函数 +static int defaultHashCode(HashMap hashMap, let key); +// 默认判断键值是否相等 +static Boolean defaultEqual(let key1, let key2); +// 默认添加键值对 +static void defaultPut(HashMap hashMap, let key, let value); +// 默认获取键对应值 +static let defaultGet(HashMap hashMap, let key); +// 默认删除键 +static let defaultRemove(HashMap hashMap, let key); +// 默认判断键是否存在 +static Boolean defaultExists(HashMap hashMap, let key); +// 默认清空Map +static void defaultClear(HashMap hashMap); +// 重新构建 +static void resetHashMap(HashMap hashMap, int listSize); +// 创建一个哈希结构 +HashMap createHashMap(HashCode hashCode, Equal equal); +// 创建哈希结构迭代器 +HashMapIterator createHashMapIterator(HashMap hashMap); +// 迭代器是否有下一个 +Boolean hasNextHashMapIterator(HashMapIterator iterator); +// 迭代到下一次 +HashMapIterator nextHashMapIterator(HashMapIterator iterator); +// 释放迭代器内存 +void freeHashMapIterator(HashMapIterator * iterator); + +int defaultHashCode(HashMap hashMap, let key) +{ + char *k = (char *)key; + unsigned long h = 0; + while(*k){ + h += (*(k + 1)) * (*(k ++)); + } + h = h >> 2; + return h % hashMap->listSize; } + Boolean defaultEqual(let key1, let key2) { - return strcmp((string)key1, (string)key2) ? False : True; + Boolean tmp = strcmp((string)key1,(string)key2); + return !tmp; } void resetHashMap(HashMap hashMap, int listSize) { @@ -35,16 +53,16 @@ void resetHashMap(HashMap hashMap, int listSize) { // 键值对临时存储空间 Entry tempList = newEntryList(hashMap->size); - HashMapIterator iterator = createHashMapIterator(hashMap); - int length = hashMap->size; - for (int index = 0; hasNextHashMapIterator(iterator); index++) { + HashMapIterator it = createHashMapIterator(hashMap); + int len = hashMap->size; + for (int idx = 0; hasNextHashMapIterator(it); idx++) { // 迭代取出所有键值对 - iterator = nextHashMapIterator(iterator); - tempList[index].key = iterator->entry->key; - tempList[index].value = iterator->entry->value; - tempList[index].next = NULL; + it = nextHashMapIterator(it); + tempList[idx].key = it->entry->key; + tempList[idx].value = it->entry->value; + tempList[idx].next = NULL; } - freeHashMapIterator(&iterator); + freeHashMapIterator(&it); // 清除原有键值对数据 hashMap->size = 0; @@ -77,25 +95,25 @@ void resetHashMap(HashMap hashMap, int listSize) { } // 将所有键值对重新写入内存 - for (int i = 0; i < length; i++) { + for (int i = 0; i < len; i++) { hashMap->put(hashMap, tempList[i].key, tempList[i].value); } free(tempList); } -void defaultPut(HashMap hashMap, let key, let value) { +void defaultput(HashMap hashMap, let key, let value) { // 获取哈希值 - int index = hashMap->hashCode(hashMap, key); + int idx = hashMap->hashCode(hashMap, key); - if (hashMap->list[index].key == NULL) { + if (hashMap->list[idx].key == NULL) { hashMap->size++; // 该地址为空时直接存储 - hashMap->list[index].key = key; - hashMap->list[index].value = value; + hashMap->list[idx].key = key; + hashMap->list[idx].value = value; } else { - Entry current = &hashMap->list[index]; + Entry current = &hashMap->list[idx]; while (current != NULL) { if (hashMap->equal(key, current->key)) { // 对于键值已经存在的直接覆盖 @@ -109,27 +127,21 @@ void defaultPut(HashMap hashMap, let key, let value) { Entry entry = newEntry(); entry->key = key; entry->value = value; - entry->next = hashMap->list[index].next; - hashMap->list[index].next = entry; + entry->next = hashMap->list[idx].next; + hashMap->list[idx].next = entry; hashMap->size++; } if (hashMap->autoAssign && hashMap->size >= hashMap->listSize) { - // 内存扩充至原来的两倍 - // *注: 扩充时考虑的是当前存储元素数量与存储空间的大小关系,而不是存储空间是否已经存满, - // 例如: 存储空间为10,存入了10个键值对,但是全部冲突了,所以存储空间空着9个,其余的全部挂在一个上面, - // 这样检索的时候和遍历查询没有什么区别了,可以简单这样理解,当我存入第11个键值对的时候一定会发生冲突, - // 这是由哈希函数本身的特性(取模)决定的,冲突就会导致检索变慢,所以这时候扩充存储空间,对原有键值对进行 - // 再次散列,会把冲突的数据再次分散开,加快索引定位速度。 resetHashMap(hashMap, hashMap->listSize * 2); } } let defaultGet(HashMap hashMap, let key) { if (hashMap->exists(hashMap, key)) { - int index = hashMap->hashCode(hashMap, key); - Entry entry = &hashMap->list[index]; + int idx = hashMap->hashCode(hashMap, key); + Entry entry = &hashMap->list[idx]; while (entry != NULL) { if (hashMap->equal(entry->key, key)) { return entry->value; @@ -141,13 +153,12 @@ let defaultGet(HashMap hashMap, let key) { } let defaultRemove(HashMap hashMap, let key) { - int index = hashMap->hashCode(hashMap, key); - Entry entry = &hashMap->list[index]; - if (entry->key == NULL) { - return NULL; - } + int idx = hashMap->hashCode(hashMap, key); + Entry entry = &hashMap->list[idx]; + if (entry->key == NULL) return NULL; + let entryKey = entry->key; - Boolean result = False; + Boolean res = False; if (hashMap->equal(entry->key, key)) { hashMap->size--; if (entry->next != NULL) { @@ -161,7 +172,7 @@ let defaultRemove(HashMap hashMap, let key) { entry->key = NULL; entry->value = NULL; } - result = True; + res = True; } else { Entry p = entry; @@ -171,7 +182,7 @@ let defaultRemove(HashMap hashMap, let key) { hashMap->size--; p->next = entry->next; free(entry); - result = True; + res = True; break; } p = entry; @@ -180,23 +191,22 @@ let defaultRemove(HashMap hashMap, let key) { } // 如果空间占用不足一半,则释放多余内存 - if (result && hashMap->autoAssign && hashMap->size < hashMap->listSize / 2) { + if (res && hashMap->autoAssign && hashMap->size < hashMap->listSize / 2) { resetHashMap(hashMap, hashMap->listSize / 2); } return entryKey; } Boolean defaultExists(HashMap hashMap, let key) { - int index = hashMap->hashCode(hashMap, key); - Entry entry = &hashMap->list[index]; + int idx = hashMap->hashCode(hashMap, key); + Entry entry = &hashMap->list[idx]; if (entry->key == NULL) { return False; } else { while (entry != NULL) { - if (hashMap->equal(entry->key, key)) { + if (hashMap->equal(entry->key, key)) return True; - } entry = entry->next; } return False; @@ -221,103 +231,102 @@ void defaultClear(HashMap hashMap) { hashMap->listSize = 0; } -HashMap createHashMap(HashCode hashCode, Equal equal) { +HashMap createHashMap(HashCode hashCode, Equal equ) { HashMap hashMap = newHashMap(); - if (hashMap == NULL) { - return NULL; - } + if (hashMap == NULL) return NULL; + hashMap->size = 0; hashMap->listSize = 8; hashMap->hashCode = hashCode == NULL ? defaultHashCode : hashCode; - hashMap->equal = equal == NULL ? defaultEqual : equal; + hashMap->equal = equ == NULL ? defaultEqual : equ; hashMap->exists = defaultExists; hashMap->get = defaultGet; - hashMap->put = defaultPut; + hashMap->put = defaultput; hashMap->remove = defaultRemove; hashMap->clear = defaultClear; hashMap->autoAssign = True; // 起始分配8个内存空间,溢出时会自动扩充 hashMap->list = newEntryList(hashMap->listSize); - if (hashMap->list == NULL) { - return NULL; - } + if (hashMap->list == NULL) return NULL; + Entry p = hashMap->list; for (int i = 0; i < hashMap->listSize; i++) { p[i].key = p[i].value = p[i].next = NULL; } + return hashMap; } HashMapIterator createHashMapIterator(HashMap hashMap) { - HashMapIterator iterator = newHashMapIterator(); - if (iterator == NULL) { - return NULL; - } - iterator->hashMap = hashMap; - iterator->count = 0; - iterator->hashCode = -1; - iterator->entry = NULL; - return iterator; + HashMapIterator it = newHashMapIterator(); + if (it == NULL) return NULL; + + it->hashMap = hashMap; + it->count = 0; + it->hashCode = -1; + it->entry = NULL; + + return it; } -Boolean hasNextHashMapIterator(HashMapIterator iterator) { - return iterator->count < iterator->hashMap->size ? True : False; +Boolean hasNextHashMapIterator(HashMapIterator it) { + int cnt = it->count,len=it->hashMap->size; + if(cntentry != NULL && iterator->entry->next != NULL) { - iterator->count++; - iterator->entry = iterator->entry->next; - return iterator; +HashMapIterator nextHashMapIterator(HashMapIterator it) { + if (hasNextHashMapIterator(it)) { + if (it->entry != NULL && it->entry->next != NULL) { + it->count++; + it->entry = it->entry->next; + return it; } - while (++iterator->hashCode < iterator->hashMap->listSize) { - Entry entry = &iterator->hashMap->list[iterator->hashCode]; + while (++it->hashCode < it->hashMap->listSize) { + Entry entry = &it->hashMap->list[it->hashCode]; if (entry->key != NULL) { - iterator->count++; - iterator->entry = entry; + it->entry = entry; + it->count++; break; } } } - return iterator; + return it; } -void freeHashMapIterator(HashMapIterator * iterator) { - free(*iterator); - *iterator = NULL; +void freeHashMapIterator(HashMapIterator * it) { + free(*it); + *it = 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) + void TestHash() { HashMap map = createHashMap(NULL, NULL); - Put(map, "000123", "Annie"); - Put(map, "000245", "Bob"); - Put(map, "000284", "Daniel"); - Put(map, "000281", "Luna"); - Put(map, "000587", "Yao"); - Put(map, "000985", "Li Ming"); - Put(map, "000852", "Janne"); + map->put(map, (void *)"000123", (void *)"Annie"); + map->put(map, (void *)"000245", (void *)"Bob"); + map->put(map, (void *)"000284", (void *)"Daniel"); + map->put(map, (void *)"000281", (void *)"Luna"); + map->put(map, (void *)"000587", (void *)"Yao"); + map->put(map, (void *)"000985", (void *)"Li Ming"); + map->put(map, (void *)"000852", (void *)"Janne"); printf("print the key-values in hashmap:\n"); - HashMapIterator iterator = createHashMapIterator(map); - while (hasNextHashMapIterator(iterator)) { - iterator = nextHashMapIterator(iterator); + HashMapIterator it = createHashMapIterator(map); + while (hasNextHashMapIterator(it)) { + it = nextHashMapIterator(it); printf("{ key: %s, key: %s, hashcode: %d }\n", - (char *)iterator->entry->key, (char *)iterator->entry->value, iterator->hashCode); + (char *)it->entry->key, (char *)it->entry->value, it->hashCode); } - printf("key: 000852, exists: %s\n", Existe(map, "000852") ? "true" : "false"); - printf("000852: %s\n", Get(map, "000852")); - printf("remove 000852 %s\n", Remove(map, "000852") ? "true" : "false"); - printf("key: 000852, exists: %s\n", Existe(map, "000852") ? "true" : "false"); + printf("key: 000852, exists: %s\n", map->exists(map, (void *)"000852") ? "true" : "false"); + printf("000852: %s\n", (char *)map->get(map, (void *)"000852")); + printf("remove 000852 %s\n", map->remove(map, (void *)"000852") ? "true" : "false"); + printf("key: 000852, exists: %s\n", map->exists(map, (void *)"000852") ? "true" : "false"); map->clear(map); - freeHashMapIterator(&iterator); + freeHashMapIterator(&it); } -PRIV_SHELL_CMD_FUNCTION(TestHash, Implement hash_map, PRIV_SHELL_CMD_MAIN_ATTR); \ No newline at end of file +PRIV_SHELL_CMD_FUNCTION(TestHash, Implement hash_map, PRIV_SHELL_CMD_MAIN_ATTR); + diff --git a/APP_Framework/Applications/app_test/test_hash/test_hash.h b/APP_Framework/Applications/app_test/test_hash/test_hash.h index 3f7358411..eaeeef001 100644 --- a/APP_Framework/Applications/app_test/test_hash/test_hash.h +++ b/APP_Framework/Applications/app_test/test_hash/test_hash.h @@ -1,13 +1,4 @@ -/** -* @file: test_hash.h -* @brief: a application of test hash function -* @version: 3.0 -* @author: Yao wenying -* @date: 2023/05/26 -*/ - - #ifndef __HASHMAP_H__ #define __HASHMAP_H__ @@ -29,8 +20,8 @@ typedef enum _Boolean Boolean; #define let void * typedef struct entry { - let key; // 键 - let value; // 值 + let key; + let value; struct entry * next; // 冲突链表 }*Entry; @@ -64,8 +55,7 @@ typedef void(*Clear)(HashMap hashMap); typedef Boolean(*Exists)(HashMap hashMap, let key); typedef struct hashMap { - int size; // 当前大小 - int listSize; // 有效空间大小 + int size,listSize; HashCode hashCode; // 哈希函数 Equal equal; // 判等函数 Entry list; // 存储区域 @@ -80,50 +70,10 @@ typedef struct hashMap { // 迭代器结构 typedef struct hashMapIterator { Entry entry; // 迭代器当前指向 - int count; // 迭代次数 - int hashCode; // 键值对的哈希值 + int count,hashCode; HashMap hashMap; }*HashMapIterator; #define newHashMapIterator() NEW(struct hashMapIterator) -// 默认哈希函数 -static int defaultHashCode(HashMap hashMap, let key); - -// 默认判断键值是否相等 -static Boolean defaultEqual(let key1, let key2); - -// 默认添加键值对 -static void defaultPut(HashMap hashMap, let key, let value); - -// 默认获取键对应值 -static let defaultGet(HashMap hashMap, let key); - -// 默认删除键 -static let defaultRemove(HashMap hashMap, let key); - -// 默认判断键是否存在 -static Boolean defaultExists(HashMap hashMap, let key); - -// 默认清空Map -static void defaultClear(HashMap hashMap); - -// 重新构建 -static void resetHashMap(HashMap hashMap, int listSize); - -// 创建一个哈希结构 -HashMap createHashMap(HashCode hashCode, Equal equal); - -// 创建哈希结构迭代器 -HashMapIterator createHashMapIterator(HashMap hashMap); - -// 迭代器是否有下一个 -Boolean hasNextHashMapIterator(HashMapIterator iterator); - -// 迭代到下一次 -HashMapIterator nextHashMapIterator(HashMapIterator iterator); - -// 释放迭代器内存 -void freeHashMapIterator(HashMapIterator * iterator); - -#endif // !__HASHMAP_H__ \ No newline at end of file +#endif // !__HASHMAP_H__