modified hash_test

This commit is contained in:
w18604545988 2023-10-06 22:01:04 -07:00
parent 3fc12f67b9
commit ce6c488b2a
2 changed files with 128 additions and 169 deletions

View File

@ -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 <transform.h> #include <transform.h>
#include"test_hash.h" #include"test_hash.h"
int defaultHashCode(HashMap hashMap, let key) { // 默认哈希函数
char * k = (char *)key; static int defaultHashCode(HashMap hashMap, let key);
unsigned long h = 0; // 默认判断键值是否相等
while (*k) { static Boolean defaultEqual(let key1, let key2);
h = (h << 4) + *k++; // 默认添加键值对
unsigned long g = h & 0xF0000000L; static void defaultPut(HashMap hashMap, let key, let value);
if (g) { // 默认获取键对应值
h ^= g >> 24; static let defaultGet(HashMap hashMap, let key);
} // 默认删除键
h &= ~g; static let defaultRemove(HashMap hashMap, let key);
} // 默认判断键是否存在
return h % hashMap->listSize; 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) { 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) { void resetHashMap(HashMap hashMap, int listSize) {
@ -35,16 +53,16 @@ void resetHashMap(HashMap hashMap, int listSize) {
// 键值对临时存储空间 // 键值对临时存储空间
Entry tempList = newEntryList(hashMap->size); Entry tempList = newEntryList(hashMap->size);
HashMapIterator iterator = createHashMapIterator(hashMap); HashMapIterator it = createHashMapIterator(hashMap);
int length = hashMap->size; int len = hashMap->size;
for (int index = 0; hasNextHashMapIterator(iterator); index++) { for (int idx = 0; hasNextHashMapIterator(it); idx++) {
// 迭代取出所有键值对 // 迭代取出所有键值对
iterator = nextHashMapIterator(iterator); it = nextHashMapIterator(it);
tempList[index].key = iterator->entry->key; tempList[idx].key = it->entry->key;
tempList[index].value = iterator->entry->value; tempList[idx].value = it->entry->value;
tempList[index].next = NULL; tempList[idx].next = NULL;
} }
freeHashMapIterator(&iterator); freeHashMapIterator(&it);
// 清除原有键值对数据 // 清除原有键值对数据
hashMap->size = 0; 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); hashMap->put(hashMap, tempList[i].key, tempList[i].value);
} }
free(tempList); 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->size++;
// 该地址为空时直接存储 // 该地址为空时直接存储
hashMap->list[index].key = key; hashMap->list[idx].key = key;
hashMap->list[index].value = value; hashMap->list[idx].value = value;
} }
else { else {
Entry current = &hashMap->list[index]; Entry current = &hashMap->list[idx];
while (current != NULL) { while (current != NULL) {
if (hashMap->equal(key, current->key)) { if (hashMap->equal(key, current->key)) {
// 对于键值已经存在的直接覆盖 // 对于键值已经存在的直接覆盖
@ -109,27 +127,21 @@ void defaultPut(HashMap hashMap, let key, let value) {
Entry entry = newEntry(); Entry entry = newEntry();
entry->key = key; entry->key = key;
entry->value = value; entry->value = value;
entry->next = hashMap->list[index].next; entry->next = hashMap->list[idx].next;
hashMap->list[index].next = entry; hashMap->list[idx].next = entry;
hashMap->size++; hashMap->size++;
} }
if (hashMap->autoAssign && hashMap->size >= hashMap->listSize) { if (hashMap->autoAssign && hashMap->size >= hashMap->listSize) {
// 内存扩充至原来的两倍 // 内存扩充至原来的两倍
// *注: 扩充时考虑的是当前存储元素数量与存储空间的大小关系,而不是存储空间是否已经存满,
// 例如: 存储空间为10存入了10个键值对但是全部冲突了所以存储空间空着9个其余的全部挂在一个上面
// 这样检索的时候和遍历查询没有什么区别了可以简单这样理解当我存入第11个键值对的时候一定会发生冲突
// 这是由哈希函数本身的特性(取模)决定的,冲突就会导致检索变慢,所以这时候扩充存储空间,对原有键值对进行
// 再次散列,会把冲突的数据再次分散开,加快索引定位速度。
resetHashMap(hashMap, hashMap->listSize * 2); resetHashMap(hashMap, hashMap->listSize * 2);
} }
} }
let defaultGet(HashMap hashMap, let key) { let defaultGet(HashMap hashMap, let key) {
if (hashMap->exists(hashMap, key)) { if (hashMap->exists(hashMap, key)) {
int index = hashMap->hashCode(hashMap, key); int idx = hashMap->hashCode(hashMap, key);
Entry entry = &hashMap->list[index]; Entry entry = &hashMap->list[idx];
while (entry != NULL) { while (entry != NULL) {
if (hashMap->equal(entry->key, key)) { if (hashMap->equal(entry->key, key)) {
return entry->value; return entry->value;
@ -141,13 +153,12 @@ let defaultGet(HashMap hashMap, let key) {
} }
let defaultRemove(HashMap hashMap, let key) { let defaultRemove(HashMap hashMap, let key) {
int index = hashMap->hashCode(hashMap, key); int idx = hashMap->hashCode(hashMap, key);
Entry entry = &hashMap->list[index]; Entry entry = &hashMap->list[idx];
if (entry->key == NULL) { if (entry->key == NULL) return NULL;
return NULL;
}
let entryKey = entry->key; let entryKey = entry->key;
Boolean result = False; Boolean res = False;
if (hashMap->equal(entry->key, key)) { if (hashMap->equal(entry->key, key)) {
hashMap->size--; hashMap->size--;
if (entry->next != NULL) { if (entry->next != NULL) {
@ -161,7 +172,7 @@ let defaultRemove(HashMap hashMap, let key) {
entry->key = NULL; entry->key = NULL;
entry->value = NULL; entry->value = NULL;
} }
result = True; res = True;
} }
else { else {
Entry p = entry; Entry p = entry;
@ -171,7 +182,7 @@ let defaultRemove(HashMap hashMap, let key) {
hashMap->size--; hashMap->size--;
p->next = entry->next; p->next = entry->next;
free(entry); free(entry);
result = True; res = True;
break; break;
} }
p = entry; 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); resetHashMap(hashMap, hashMap->listSize / 2);
} }
return entryKey; return entryKey;
} }
Boolean defaultExists(HashMap hashMap, let key) { Boolean defaultExists(HashMap hashMap, let key) {
int index = hashMap->hashCode(hashMap, key); int idx = hashMap->hashCode(hashMap, key);
Entry entry = &hashMap->list[index]; Entry entry = &hashMap->list[idx];
if (entry->key == NULL) { if (entry->key == NULL) {
return False; return False;
} }
else { else {
while (entry != NULL) { while (entry != NULL) {
if (hashMap->equal(entry->key, key)) { if (hashMap->equal(entry->key, key))
return True; return True;
}
entry = entry->next; entry = entry->next;
} }
return False; return False;
@ -221,103 +231,102 @@ void defaultClear(HashMap hashMap) {
hashMap->listSize = 0; hashMap->listSize = 0;
} }
HashMap createHashMap(HashCode hashCode, Equal equal) { HashMap createHashMap(HashCode hashCode, Equal equ) {
HashMap hashMap = newHashMap(); HashMap hashMap = newHashMap();
if (hashMap == NULL) { if (hashMap == NULL) return NULL;
return NULL;
}
hashMap->size = 0; hashMap->size = 0;
hashMap->listSize = 8; hashMap->listSize = 8;
hashMap->hashCode = hashCode == NULL ? defaultHashCode : hashCode; hashMap->hashCode = hashCode == NULL ? defaultHashCode : hashCode;
hashMap->equal = equal == NULL ? defaultEqual : equal; hashMap->equal = equ == NULL ? defaultEqual : equ;
hashMap->exists = defaultExists; hashMap->exists = defaultExists;
hashMap->get = defaultGet; hashMap->get = defaultGet;
hashMap->put = defaultPut; hashMap->put = defaultput;
hashMap->remove = defaultRemove; hashMap->remove = defaultRemove;
hashMap->clear = defaultClear; hashMap->clear = defaultClear;
hashMap->autoAssign = True; hashMap->autoAssign = True;
// 起始分配8个内存空间溢出时会自动扩充 // 起始分配8个内存空间溢出时会自动扩充
hashMap->list = newEntryList(hashMap->listSize); hashMap->list = newEntryList(hashMap->listSize);
if (hashMap->list == NULL) { if (hashMap->list == NULL) return NULL;
return NULL;
}
Entry p = hashMap->list; Entry p = hashMap->list;
for (int i = 0; i < hashMap->listSize; i++) { for (int i = 0; i < hashMap->listSize; i++) {
p[i].key = p[i].value = p[i].next = NULL; p[i].key = p[i].value = p[i].next = NULL;
} }
return hashMap; return hashMap;
} }
HashMapIterator createHashMapIterator(HashMap hashMap) { HashMapIterator createHashMapIterator(HashMap hashMap) {
HashMapIterator iterator = newHashMapIterator(); HashMapIterator it = newHashMapIterator();
if (iterator == NULL) { if (it == NULL) return NULL;
return NULL;
} it->hashMap = hashMap;
iterator->hashMap = hashMap; it->count = 0;
iterator->count = 0; it->hashCode = -1;
iterator->hashCode = -1; it->entry = NULL;
iterator->entry = NULL;
return iterator; return it;
} }
Boolean hasNextHashMapIterator(HashMapIterator iterator) { Boolean hasNextHashMapIterator(HashMapIterator it) {
return iterator->count < iterator->hashMap->size ? True : False; int cnt = it->count,len=it->hashMap->size;
if(cnt<len) return True;
return False;
} }
HashMapIterator nextHashMapIterator(HashMapIterator iterator) { HashMapIterator nextHashMapIterator(HashMapIterator it) {
if (hasNextHashMapIterator(iterator)) { if (hasNextHashMapIterator(it)) {
if (iterator->entry != NULL && iterator->entry->next != NULL) { if (it->entry != NULL && it->entry->next != NULL) {
iterator->count++; it->count++;
iterator->entry = iterator->entry->next; it->entry = it->entry->next;
return iterator; return it;
} }
while (++iterator->hashCode < iterator->hashMap->listSize) { while (++it->hashCode < it->hashMap->listSize) {
Entry entry = &iterator->hashMap->list[iterator->hashCode]; Entry entry = &it->hashMap->list[it->hashCode];
if (entry->key != NULL) { if (entry->key != NULL) {
iterator->count++; it->entry = entry;
iterator->entry = entry; it->count++;
break; break;
} }
} }
} }
return iterator; return it;
} }
void freeHashMapIterator(HashMapIterator * iterator) { void freeHashMapIterator(HashMapIterator * it) {
free(*iterator); free(*it);
*iterator = NULL; *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() { void TestHash() {
HashMap map = createHashMap(NULL, NULL); HashMap map = createHashMap(NULL, NULL);
Put(map, "000123", "Annie"); map->put(map, (void *)"000123", (void *)"Annie");
Put(map, "000245", "Bob"); map->put(map, (void *)"000245", (void *)"Bob");
Put(map, "000284", "Daniel"); map->put(map, (void *)"000284", (void *)"Daniel");
Put(map, "000281", "Luna"); map->put(map, (void *)"000281", (void *)"Luna");
Put(map, "000587", "Yao"); map->put(map, (void *)"000587", (void *)"Yao");
Put(map, "000985", "Li Ming"); map->put(map, (void *)"000985", (void *)"Li Ming");
Put(map, "000852", "Janne"); map->put(map, (void *)"000852", (void *)"Janne");
printf("print the key-values in hashmap:\n"); printf("print the key-values in hashmap:\n");
HashMapIterator iterator = createHashMapIterator(map); HashMapIterator it = createHashMapIterator(map);
while (hasNextHashMapIterator(iterator)) { while (hasNextHashMapIterator(it)) {
iterator = nextHashMapIterator(iterator); it = nextHashMapIterator(it);
printf("{ key: %s, key: %s, hashcode: %d }\n", 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("key: 000852, exists: %s\n", map->exists(map, (void *)"000852") ? "true" : "false");
printf("000852: %s\n", Get(map, "000852")); printf("000852: %s\n", (char *)map->get(map, (void *)"000852"));
printf("remove 000852 %s\n", Remove(map, "000852") ? "true" : "false"); printf("remove 000852 %s\n", map->remove(map, (void *)"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");
map->clear(map); map->clear(map);
freeHashMapIterator(&iterator); freeHashMapIterator(&it);
} }
PRIV_SHELL_CMD_FUNCTION(TestHash, Implement hash_map, PRIV_SHELL_CMD_MAIN_ATTR); PRIV_SHELL_CMD_FUNCTION(TestHash, Implement hash_map, PRIV_SHELL_CMD_MAIN_ATTR);

View File

@ -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__ #ifndef __HASHMAP_H__
#define __HASHMAP_H__ #define __HASHMAP_H__
@ -29,8 +20,8 @@ typedef enum _Boolean Boolean;
#define let void * #define let void *
typedef struct entry { typedef struct entry {
let key; // 键 let key;
let value; // 值 let value;
struct entry * next; // 冲突链表 struct entry * next; // 冲突链表
}*Entry; }*Entry;
@ -64,8 +55,7 @@ typedef void(*Clear)(HashMap hashMap);
typedef Boolean(*Exists)(HashMap hashMap, let key); typedef Boolean(*Exists)(HashMap hashMap, let key);
typedef struct hashMap { typedef struct hashMap {
int size; // 当前大小 int size,listSize;
int listSize; // 有效空间大小
HashCode hashCode; // 哈希函数 HashCode hashCode; // 哈希函数
Equal equal; // 判等函数 Equal equal; // 判等函数
Entry list; // 存储区域 Entry list; // 存储区域
@ -80,50 +70,10 @@ typedef struct hashMap {
// 迭代器结构 // 迭代器结构
typedef struct hashMapIterator { typedef struct hashMapIterator {
Entry entry; // 迭代器当前指向 Entry entry; // 迭代器当前指向
int count; // 迭代次数 int count,hashCode;
int hashCode; // 键值对的哈希值
HashMap hashMap; HashMap hashMap;
}*HashMapIterator; }*HashMapIterator;
#define newHashMapIterator() NEW(struct 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__ #endif // !__HASHMAP_H__