This commit is contained in:
yu 2023-09-27 10:56:26 +08:00
parent 1a6ee0234b
commit c5c39cd27c
15 changed files with 127 additions and 161 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 398 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

View File

@ -1,15 +1,115 @@
/**
* @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<stdlib.h>
#include<string.h>
#include<stdio.h>
#define NEW(type) (type *)malloc(sizeof(type))
#define let void *
// 布尔类型
enum _Boolean { True = 1, False = 0 };
typedef enum _Boolean Boolean;
//***定义键值对结构***
typedef struct entry {
let key; // 键
let value; // 值
struct entry * next; // 冲突链表
}*Entry;
#define newEntry() NEW(struct entry)
#define newEntryList(length) (Entry)malloc(length * sizeof(struct entry))
//***定义HashMap结构体***
// 哈希结构
typedef struct hashMap *HashMap;
#define newHashMap() NEW(struct hashMap)
// 哈希函数类型
typedef int(*HashCode)(HashMap, let key);
// 判等函数类型
typedef Boolean(*Equal)(let key1, let key2);
// 添加键函数类型
typedef void(*Put)(HashMap hashMap, let key, let value);
// 获取键对应值的函数类型
typedef let(*Get)(HashMap hashMap, let key);
// 删除键的函数类型
typedef let(*Remove)(HashMap hashMap, let key);
// 清空Map的函数类型
typedef void(*Clear)(HashMap hashMap);
// 判断键值是否存在的函数类型
typedef Boolean(*Exists)(HashMap hashMap, let 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, 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);
// 迭代器结构
typedef struct hashMapIterator {
Entry entry; // 迭代器当前指向
int count; // 迭代次数
int hashCode; // 键值对的哈希值
HashMap hashMap;
}*HashMapIterator;
#define newHashMapIterator() NEW(struct hashMapIterator)
// 创建哈希结构迭代器
HashMapIterator createHashMapIterator(HashMap hashMap);
// 迭代器是否有下一个
Boolean hasNextHashMapIterator(HashMapIterator iterator);
// 迭代到下一次
HashMapIterator nextHashMapIterator(HashMapIterator iterator);
// 释放迭代器内存
void freeHashMapIterator(HashMapIterator * iterator);
//***哈希函数***
int defaultHashCode(HashMap hashMap, let key) { int defaultHashCode(HashMap hashMap, let key) {
char * k = (char *)key; char * k = (char *)key;
unsigned long h = 0; unsigned long h = 0;
@ -25,7 +125,7 @@ int defaultHashCode(HashMap hashMap, let key) {
} }
Boolean defaultEqual(let key1, let key2) { Boolean defaultEqual(let key1, let key2) {
return strcmp((string)key1, (string)key2) ? False : True; return strcmp((char *)key1, (char *)key2) ? False : True;
} }
void resetHashMap(HashMap hashMap, int listSize) { void resetHashMap(HashMap hashMap, int listSize) {
@ -83,6 +183,7 @@ void resetHashMap(HashMap hashMap, int listSize) {
free(tempList); free(tempList);
} }
//***put函数***
void defaultPut(HashMap hashMap, let key, let value) { void defaultPut(HashMap hashMap, let key, let value) {
// 获取哈希值 // 获取哈希值
int index = hashMap->hashCode(hashMap, key); int index = hashMap->hashCode(hashMap, key);
@ -115,13 +216,6 @@ void defaultPut(HashMap hashMap, let key, let value) {
} }
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);
} }
} }
@ -295,29 +389,30 @@ void freeHashMapIterator(HashMapIterator * iterator) {
#define Existe(map, key) map->exists(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"); Put(map, "abcdef", "Hello");
Put(map, "000245", "Bob"); Put(map, "123456", "Xia");
Put(map, "000284", "Daniel"); Put(map, "789654", "Yi");
Put(map, "000281", "Luna"); Put(map, "4545", "Dui");
Put(map, "000587", "Yao"); Put(map, "857", "capybara");
Put(map, "000985", "Li Ming"); Put(map, "ohohoh", "haha");
Put(map, "000852", "Janne"); Put(map, "wangwang", "dog");
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");
printf("print the key-values in hashmap:\n");
HashMapIterator iterator = createHashMapIterator(map); HashMapIterator iterator = createHashMapIterator(map);
while (hasNextHashMapIterator(iterator)) { while (hasNextHashMapIterator(iterator)) {
iterator = nextHashMapIterator(iterator); iterator = nextHashMapIterator(iterator);
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 *)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("remove 000852 %s\n", Remove(map, "000852") ? "true" : "false");
printf("key: 000852, exists: %s\n", Existe(map, "000852") ? "true" : "false");
map->clear(map); map->clear(map);
freeHashMapIterator(&iterator); 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);

View File

@ -1,129 +0,0 @@
/**
* @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__
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
// 实现数据的基本类型
// 字符串类型
#define string char *
#define newString(str) strcpy((char *)malloc(strlen(str) + 1), str)
#define NEW(type) (type *)malloc(sizeof(type))
// 布尔类型
enum _Boolean { True = 1, False = 0 };
typedef enum _Boolean Boolean;
#define let void *
typedef struct entry {
let key; // 键
let value; // 值
struct entry * next; // 冲突链表
}*Entry;
#define newEntry() NEW(struct entry)
#define newEntryList(length) (Entry)malloc(length * sizeof(struct entry))
// 哈希结构
typedef struct hashMap *HashMap;
#define newHashMap() NEW(struct hashMap)
// 哈希函数类型
typedef int(*HashCode)(HashMap, let key);
// 判等函数类型
typedef Boolean(*Equal)(let key1, let key2);
// 添加键函数类型
typedef void(*Put)(HashMap hashMap, let key, let value);
// 获取键对应值的函数类型
typedef let(*Get)(HashMap hashMap, let key);
// 删除键的函数类型
typedef let(*Remove)(HashMap hashMap, let key);
// 清空Map的函数类型
typedef void(*Clear)(HashMap hashMap);
// 判断键值是否存在的函数类型
typedef Boolean(*Exists)(HashMap hashMap, let 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;
// 迭代器结构
typedef struct hashMapIterator {
Entry entry; // 迭代器当前指向
int count; // 迭代次数
int 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__