warmup
Before Width: | Height: | Size: 75 KiB |
Before Width: | Height: | Size: 102 KiB |
Before Width: | Height: | Size: 94 KiB |
Before Width: | Height: | Size: 95 KiB |
After Width: | Height: | Size: 76 KiB |
After Width: | Height: | Size: 194 KiB |
After Width: | Height: | Size: 51 KiB |
After Width: | Height: | Size: 67 KiB |
After Width: | Height: | Size: 176 KiB |
After Width: | Height: | Size: 398 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 128 KiB |
|
@ -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);
|
|
|
@ -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__
|
|