Update test_hash.c

This commit is contained in:
kyt_2002 2023-10-05 19:01:15 +08:00
parent a6505f3731
commit b20768ff97
1 changed files with 320 additions and 322 deletions

View File

@ -1,323 +1,321 @@
#include <transform.h>
/** #include "test_hash.h"
* @file: test_hash.c
* @brief: a application of test hash function // 默认的哈希函数,将字符串键转换为哈希码
* @version: 3.0 int defaultHashCode(HashMap hashMap, let key) {
* @author: Yao wenying char * k = (char *)key;
* @date: 2023/05/26 unsigned long h = 0;
*/ while (*k) {
h = (h << 4) + *k++;
#include <transform.h> unsigned long g = h & 0xF0000000L;
#include"test_hash.h" if (g) {
h ^= g >> 24;
int defaultHashCode(HashMap hashMap, let key) { }
char * k = (char *)key; h &= ~g;
unsigned long h = 0; }
while (*k) { return h % hashMap->listSize;
h = (h << 4) + *k++; }
unsigned long g = h & 0xF0000000L;
if (g) { // 默认的键相等判断函数,比较两个字符串是否相等
h ^= g >> 24; Boolean defaultEqual(let key1, let key2) {
} return strcmp((string)key1, (string)key2) ? False : True;
h &= ~g; }
}
return h % hashMap->listSize; // 重置哈希表的大小
} void resetHashMap(HashMap hashMap, int listSize) {
if (listSize < 8) return;
Boolean defaultEqual(let key1, let key2) {
return strcmp((string)key1, (string)key2) ? False : True; // 键值对临时存储空间
} Entry tempList = newEntryList(hashMap->size);
void resetHashMap(HashMap hashMap, int listSize) { HashMapIterator iterator = createHashMapIterator(hashMap);
int length = hashMap->size;
if (listSize < 8) return; for (int index = 0; hasNextHashMapIterator(iterator); index++) {
// 迭代取出所有键值对
// 键值对临时存储空间 iterator = nextHashMapIterator(iterator);
Entry tempList = newEntryList(hashMap->size); tempList[index].key = iterator->entry->key;
tempList[index].value = iterator->entry->value;
HashMapIterator iterator = createHashMapIterator(hashMap); tempList[index].next = NULL;
int length = hashMap->size; }
for (int index = 0; hasNextHashMapIterator(iterator); index++) { freeHashMapIterator(&iterator);
// 迭代取出所有键值对
iterator = nextHashMapIterator(iterator); // 清除原有键值对数据
tempList[index].key = iterator->entry->key; hashMap->size = 0;
tempList[index].value = iterator->entry->value; for (int i = 0; i < hashMap->listSize; i++) {
tempList[index].next = NULL; Entry current = &hashMap->list[i];
} current->key = NULL;
freeHashMapIterator(&iterator); current->value = NULL;
if (current->next != NULL) {
// 清除原有键值对数据 while (current->next != NULL) {
hashMap->size = 0; Entry temp = current->next->next;
for (int i = 0; i < hashMap->listSize; i++) { free(current->next);
Entry current = &hashMap->list[i]; current->next = temp;
current->key = NULL; }
current->value = NULL; }
if (current->next != NULL) { }
while (current->next != NULL) {
Entry temp = current->next->next; // 更改内存大小
free(current->next); hashMap->listSize = listSize;
current->next = temp; Entry relist = (Entry)realloc(hashMap->list, hashMap->listSize * sizeof(struct entry));
} if (relist != NULL) {
} hashMap->list = relist;
} relist = NULL;
}
// 更改内存大小
hashMap->listSize = listSize; // 初始化数据
Entry relist = (Entry)realloc(hashMap->list, hashMap->listSize * sizeof(struct entry)); for (int i = 0; i < hashMap->listSize; i++) {
if (relist != NULL) { hashMap->list[i].key = NULL;
hashMap->list = relist; hashMap->list[i].value = NULL;
relist = NULL; hashMap->list[i].next = NULL;
} }
// 初始化数据 // 将所有键值对重新写入内存
for (int i = 0; i < hashMap->listSize; i++) { for (int i = 0; i < length; i++) {
hashMap->list[i].key = NULL; hashMap->put(hashMap, tempList[i].key, tempList[i].value);
hashMap->list[i].value = NULL; }
hashMap->list[i].next = NULL; free(tempList);
} }
// 将所有键值对重新写入内存 // 默认的键值对插入函数
for (int i = 0; i < length; i++) { void defaultPut(HashMap hashMap, let key, let value) {
hashMap->put(hashMap, tempList[i].key, tempList[i].value); // 获取哈希值
} int index = hashMap->hashCode(hashMap, key);
free(tempList);
} if (hashMap->list[index].key == NULL) {
hashMap->size++;
void defaultPut(HashMap hashMap, let key, let value) { // 该地址为空时直接存储
// 获取哈希值 hashMap->list[index].key = key;
int index = hashMap->hashCode(hashMap, key); hashMap->list[index].value = value;
}
if (hashMap->list[index].key == NULL) { else {
hashMap->size++; Entry current = &hashMap->list[index];
// 该地址为空时直接存储 while (current != NULL) {
hashMap->list[index].key = key; if (hashMap->equal(key, current->key)) {
hashMap->list[index].value = value; // 对于键值已经存在的直接覆盖
} current->value = value;
else { return;
}
Entry current = &hashMap->list[index]; current = current->next;
while (current != NULL) { };
if (hashMap->equal(key, current->key)) {
// 对于键值已经存在的直接覆盖 // 发生冲突则创建节点挂到相应位置的next上
current->value = value; Entry entry = newEntry();
return; entry->key = key;
} entry->value = value;
current = current->next; entry->next = hashMap->list[index].next;
}; hashMap->list[index].next = entry;
hashMap->size++;
// 发生冲突则创建节点挂到相应位置的next上 }
Entry entry = newEntry();
entry->key = key; if (hashMap->autoAssign && hashMap->size >= hashMap->listSize) {
entry->value = value; // 内存扩充至原来的两倍
entry->next = hashMap->list[index].next; resetHashMap(hashMap, hashMap->listSize * 2);
hashMap->list[index].next = entry; }
hashMap->size++; }
}
// 默认的获取值函数
if (hashMap->autoAssign && hashMap->size >= hashMap->listSize) { let defaultGet(HashMap hashMap, let key) {
if (hashMap->exists(hashMap, key)) {
// 内存扩充至原来的两倍 int index = hashMap->hashCode(hashMap, key);
// *注: 扩充时考虑的是当前存储元素数量与存储空间的大小关系,而不是存储空间是否已经存满, Entry entry = &hashMap->list[index];
// 例如: 存储空间为10存入了10个键值对但是全部冲突了所以存储空间空着9个其余的全部挂在一个上面 while (entry != NULL) {
// 这样检索的时候和遍历查询没有什么区别了可以简单这样理解当我存入第11个键值对的时候一定会发生冲突 if (hashMap->equal(entry->key, key)) {
// 这是由哈希函数本身的特性(取模)决定的,冲突就会导致检索变慢,所以这时候扩充存储空间,对原有键值对进行 return entry->value;
// 再次散列,会把冲突的数据再次分散开,加快索引定位速度。 }
resetHashMap(hashMap, hashMap->listSize * 2); entry = entry->next;
} }
} }
return NULL;
let defaultGet(HashMap hashMap, let key) { }
if (hashMap->exists(hashMap, key)) {
int index = hashMap->hashCode(hashMap, key); // 默认的删除键值对函数
Entry entry = &hashMap->list[index]; let defaultRemove(HashMap hashMap, let key) {
while (entry != NULL) { int index = hashMap->hashCode(hashMap, key);
if (hashMap->equal(entry->key, key)) { Entry entry = &hashMap->list[index];
return entry->value; if (entry->key == NULL) {
} return NULL;
entry = entry->next; }
} let entryKey = entry->key;
} Boolean result = False;
return NULL; if (hashMap->equal(entry->key, key)) {
} hashMap->size--;
if (entry->next != NULL) {
let defaultRemove(HashMap hashMap, let key) { Entry temp = entry->next;
int index = hashMap->hashCode(hashMap, key); entry->key = temp->key;
Entry entry = &hashMap->list[index]; entry->value = temp->value;
if (entry->key == NULL) { entry->next = temp->next;
return NULL; free(temp);
} }
let entryKey = entry->key; else {
Boolean result = False; entry->key = NULL;
if (hashMap->equal(entry->key, key)) { entry->value = NULL;
hashMap->size--; }
if (entry->next != NULL) { result = True;
Entry temp = entry->next; }
entry->key = temp->key; else {
entry->value = temp->value; Entry p = entry;
entry->next = temp->next; entry = entry->next;
free(temp); while (entry != NULL) {
} if (hashMap->equal(entry->key, key)) {
else { hashMap->size--;
entry->key = NULL; p->next = entry->next;
entry->value = NULL; free(entry);
} result = True;
result = True; break;
} }
else { p = entry;
Entry p = entry; entry = entry->next;
entry = entry->next; };
while (entry != NULL) { }
if (hashMap->equal(entry->key, key)) {
hashMap->size--; // 如果空间占用不足一半,则释放多余内存
p->next = entry->next; if (result && hashMap->autoAssign && hashMap->size < hashMap->listSize / 2) {
free(entry); resetHashMap(hashMap, hashMap->listSize / 2);
result = True; }
break; return entryKey;
} }
p = entry;
entry = entry->next; // 默认的判断键是否存在函数
}; Boolean defaultExists(HashMap hashMap, let key) {
} int index = hashMap->hashCode(hashMap, key);
Entry entry = &hashMap->list[index];
// 如果空间占用不足一半,则释放多余内存 if (entry->key == NULL) {
if (result && hashMap->autoAssign && hashMap->size < hashMap->listSize / 2) { return False;
resetHashMap(hashMap, hashMap->listSize / 2); }
} else {
return entryKey; while (entry != NULL) {
} if (hashMap->equal(entry->key, key)) {
return True;
Boolean defaultExists(HashMap hashMap, let key) { }
int index = hashMap->hashCode(hashMap, key); entry = entry->next;
Entry entry = &hashMap->list[index]; }
if (entry->key == NULL) { return False;
return False; }
} }
else {
while (entry != NULL) { // 默认的清空哈希表函数
if (hashMap->equal(entry->key, key)) { void defaultClear(HashMap hashMap) {
return True; for (int i = 0; i < hashMap->listSize; i++) {
} // 释放冲突值内存
entry = entry->next; Entry entry = hashMap->list[i].next;
} while (entry != NULL) {
return False; Entry next = entry->next;
} free(entry);
} entry = next;
}
void defaultClear(HashMap hashMap) { hashMap->list[i].next = NULL;
for (int i = 0; i < hashMap->listSize; i++) { }
// 释放冲突值内存 // 释放存储空间
Entry entry = hashMap->list[i].next; free(hashMap->list);
while (entry != NULL) { hashMap->list = NULL;
Entry next = entry->next; hashMap->size = -1;
free(entry); hashMap->listSize = 0;
entry = next; }
}
hashMap->list[i].next = NULL; // 创建一个哈希表
} HashMap createHashMap(HashCode hashCode, Equal equal) {
// 释放存储空间 HashMap hashMap = newHashMap();
free(hashMap->list); if (hashMap == NULL) {
hashMap->list = NULL; return NULL;
hashMap->size = -1; }
hashMap->listSize = 0; hashMap->size = 0;
} hashMap->listSize = 8;
hashMap->hashCode = hashCode == NULL ? defaultHashCode : hashCode;
HashMap createHashMap(HashCode hashCode, Equal equal) { hashMap->equal = equal == NULL ? defaultEqual : equal;
HashMap hashMap = newHashMap(); hashMap->exists = defaultExists;
if (hashMap == NULL) { hashMap->get = defaultGet;
return NULL; hashMap->put = defaultPut;
} hashMap->remove = defaultRemove;
hashMap->size = 0; hashMap->clear = defaultClear;
hashMap->listSize = 8; hashMap->autoAssign = True;
hashMap->hashCode = hashCode == NULL ? defaultHashCode : hashCode;
hashMap->equal = equal == NULL ? defaultEqual : equal; // 起始分配8个内存空间溢出时会自动扩充
hashMap->exists = defaultExists; hashMap->list = newEntryList(hashMap->listSize);
hashMap->get = defaultGet; if (hashMap->list == NULL) {
hashMap->put = defaultPut; return NULL;
hashMap->remove = defaultRemove; }
hashMap->clear = defaultClear; Entry p = hashMap->list;
hashMap->autoAssign = True; for (int i = 0; i < hashMap->listSize; i++) {
p[i].key = p[i].value = p[i].next = NULL;
// 起始分配8个内存空间溢出时会自动扩充 }
hashMap->list = newEntryList(hashMap->listSize); return hashMap;
if (hashMap->list == NULL) { }
return NULL;
} // 创建一个哈希表迭代器
Entry p = hashMap->list; HashMapIterator createHashMapIterator(HashMap hashMap) {
for (int i = 0; i < hashMap->listSize; i++) { HashMapIterator iterator = newHashMapIterator();
p[i].key = p[i].value = p[i].next = NULL; if (iterator == NULL) {
} return NULL;
return hashMap; }
} iterator->hashMap = hashMap;
iterator->count = 0;
HashMapIterator createHashMapIterator(HashMap hashMap) { iterator->hashCode = -1;
HashMapIterator iterator = newHashMapIterator(); iterator->entry = NULL;
if (iterator == NULL) { return iterator;
return NULL; }
}
iterator->hashMap = hashMap; // 判断迭代器是否还有下一个元素
iterator->count = 0; Boolean hasNextHashMapIterator(HashMapIterator iterator) {
iterator->hashCode = -1; return iterator->count < iterator->hashMap->size ? True : False;
iterator->entry = NULL; }
return iterator;
} // 获取迭代器的下一个元素
HashMapIterator nextHashMapIterator(HashMapIterator iterator) {
Boolean hasNextHashMapIterator(HashMapIterator iterator) { if (hasNextHashMapIterator(iterator)) {
return iterator->count < iterator->hashMap->size ? True : False; if (iterator->entry != NULL && iterator->entry->next != NULL) {
} iterator->count++;
iterator->entry = iterator->entry->next;
HashMapIterator nextHashMapIterator(HashMapIterator iterator) { return iterator;
if (hasNextHashMapIterator(iterator)) { }
if (iterator->entry != NULL && iterator->entry->next != NULL) { while (++iterator->hashCode < iterator->hashMap->listSize) {
iterator->count++; Entry entry = &iterator->hashMap->list[iterator->hashCode];
iterator->entry = iterator->entry->next; if (entry->key != NULL) {
return iterator; iterator->count++;
} iterator->entry = entry;
while (++iterator->hashCode < iterator->hashMap->listSize) { break;
Entry entry = &iterator->hashMap->list[iterator->hashCode]; }
if (entry->key != NULL) { }
iterator->count++; }
iterator->entry = entry; return iterator;
break; }
}
} // 释放哈希表迭代器
} void freeHashMapIterator(HashMapIterator * iterator) {
return iterator; free(*iterator);
} *iterator = NULL;
}
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 Put(map, key, value) map->put(map, (void *)key, (void *)value); #define Remove(map, key) map->remove(map, (void *)key)
#define Get(map, key) (char *)map->get(map, (void *)key) #define Existe(map, key) map->exists(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);
void TestHash() { Put(map, "000123", "Annie");
HashMap map = createHashMap(NULL, NULL); Put(map, "000245", "Bob");
Put(map, "000123", "Annie"); Put(map, "000284", "Daniel");
Put(map, "000245", "Bob"); Put(map, "000281", "Luna");
Put(map, "000284", "Daniel"); Put(map, "000587", "Yao");
Put(map, "000281", "Luna"); Put(map, "000985", "Li Ming");
Put(map, "000587", "Yao"); Put(map, "000852", "Janne");
Put(map, "000985", "Li Ming");
Put(map, "000852", "Janne"); printf("print the key-values in hashmap:\n");
HashMapIterator iterator = createHashMapIterator(map);
printf("print the key-values in hashmap:\n"); while (hasNextHashMapIterator(iterator)) {
HashMapIterator iterator = createHashMapIterator(map); iterator = nextHashMapIterator(iterator);
while (hasNextHashMapIterator(iterator)) { printf("{ key: %s, key: %s, hashcode: %d }\n",
iterator = nextHashMapIterator(iterator); (char *)iterator->entry->key, (char *)iterator->entry->value, iterator->hashCode);
printf("{ key: %s, key: %s, hashcode: %d }\n", }
(char *)iterator->entry->key, (char *)iterator->entry->value, iterator->hashCode); printf("key: 000852, exists: %s\n", Existe(map, "000852") ? "true" : "false");
} printf("000852: %s\n", Get(map, "000852"));
printf("key: 000852, exists: %s\n", Existe(map, "000852") ? "true" : "false"); printf("remove 000852 %s\n", Remove(map, "000852") ? "true" : "false");
printf("000852: %s\n", Get(map, "000852")); printf("key: 000852, exists: %s\n", Existe(map, "000852") ? "true" : "false");
printf("remove 000852 %s\n", Remove(map, "000852") ? "true" : "false");
printf("key: 000852, exists: %s\n", Existe(map, "000852") ? "true" : "false"); map->clear(map);
freeHashMapIterator(&iterator);
map->clear(map); }
freeHashMapIterator(&iterator);
}
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);