采用链表法解决哈希冲突的键值对映射表,存储单一类型数据
ChainMap_S (Chain Map Single Data) 是一种采用链表法(Separate Chaining)解决哈希冲突的 Map 数据结构。它将哈希值相同的元素存储在同一个链表中,适合数据量较大且分布不均匀的场景。
// ChainMap_S 中的 Entry 类型
typedef struct Entry_S_inChainMap {
Data_S key; // 键
Data_S value; // 值
bool isEmpty; // 是否为空
} Entry_S_inChainMap;
// ChainMap_S 链表节点
typedef struct Node_S_inChainMap {
struct Node_S_inChainMap* next;
struct Node_S_inChainMap* prev;
Entry_S_inChainMap entry;
} Node_S_inChainMap;
// ChainMap_S 链表
typedef struct List_S_inChainMap {
Node_S_inChainMap* head;
Node_S_inChainMap* tail;
int size;
} List_S_inChainMap;
// ChainMap_S
typedef struct ChainMap_S {
List_S_inChainMap* arr; // 哈希桶数组
InfoOfData* keyInfo; // key 操作集
InfoOfData* valInfo; // value 操作集
int mod; // 取模基数
int len; // 哈希桶数量
int size; // 元素数量
} ChainMap_S;
#include "base.h"
#include "Map/ChainMap/Single_Data/chainmap_sdata.h"
#include "Oper/String_Info/string_info.h"
#include "Oper/Int_Info/int_info.h"
int main() {
// 1. 初始化 Map
ChainMap_S map;
initSChainMap(&map, &Info_String, &Info_Int);
// 2. 插入键值对
insertSKeyAndSValInSChainMap(&map,
Data_S_OWN("age", NULL),
Data_S_OWN(25, NULL));
insertSKeyAndSValInSChainMap(&map,
Data_S_OWN("score", NULL),
Data_S_OWN(100, NULL));
// 3. 查找
Data_S val = getCopySValBySKeyInSChianMap(&map, Data_S_OWN("age", NULL));
if (!val.isEmpty) {
printf("age: %d\n", *(int*)val.data);
}
// 4. 打印
printSChainMap(&map);
// 5. 释放
freeSChainMap(&map);
return 0;
}
初始化 ChainMap_S
pMap - ChainMap_S 的指针keyInfo - key 的 InfoOfData 类型指针valInfo - val 的 InfoOfData 类型指针释放掉复制来的在 ChainMap_S 中的 SVal
pMap - ChainMap_S 的指针valData - SVal 类型指针 (Data_S 类型)释放掉复制来的在 ChainMap_S 中的 SEntry (Entry_S_inChainMap 类型)
pMap - ChainMap_S 的指针entry - SEntry 类型 (Entry_S_inChainMap 类型)释放掉 ChainMap_S
pMap - ChainMap_S 的指针插入 key 和 val 到 ChainMap_S 类型中去
pMap - ChainMap_S 的指针key - 传入的 key (Data_S 类型数据)val - 传入的 val (Data_S 类型数据)通过 SKey 得到复制来的 SVal (Data_S 类型)
pMap - ChainMap_S 的指针key - 传入的 key (Data_S 类型数据)通过 SKey 得到 SVal (Data_S 类型),可直接修改内部的 void* data 和 void* content 内容
pMap - ChainMap_S 的指针key - 传入的 key (Data_S 类型数据)通过 SKey 得到复制来的 SEntry (Entry_S_inChainMap 类型)
pMap - ChainMap_S 的指针key - 传入的 key (Data_S 类型数据)判断 Skey 是否在 ChainMap_S 中
pMap - ChainMap_S 的指针key - 传入的 key (Data_S 类型数据)通过 SKey 删除在 ChainMap_S 中的元素
pMap - ChainMap_S 的指针key - 传入的 key (Data_S 类型数据)打印 ChainMap_S 中的所有数据
pMap - ChainMap_S 的指针打印在 ChainMap_S 中的 SKey (Data_S 类型)
pMap - ChainMap_S 的指针keyData - SKey (Data_S 类型)打印在 ChainMap_S 中的 SVal (Data_S 类型)
pMap - ChainMap_S 的指针valData - SVal (Data_S 类型)打印在 ChainMap_S 中的 SEntry (Entry_S_inChainMap 类型)
pMap - ChainMap_S 的指针entry - SEntry (Entry_S_inChainMap 类型)#include <stdio.h>
#include "base.h"
#include "Map/ChainMap/Single_Data/chainmap_sdata.h"
#include "Oper/String_Info/string_info.h"
#include "Oper/Int_Info/int_info.h"
int main() {
// 初始化 Map
ChainMap_S map;
initSChainMap(&map, &Info_String, &Info_Int);
// 插入数据
printf("=== 插入数据 ===\n");
insertSKeyAndSValInSChainMap(&map,
Data_S_OWN("apple", NULL),
Data_S_OWN(10, NULL));
insertSKeyAndSValInSChainMap(&map,
Data_S_OWN("banana", NULL),
Data_S_OWN(5, NULL));
insertSKeyAndSValInSChainMap(&map,
Data_S_OWN("orange", NULL),
Data_S_OWN(8, NULL));
printSChainMap(&map);
// 查询
printf("\n=== 查询数据 ===\n");
Data_S val = getCopySValBySKeyInSChianMap(&map, Data_S_OWN("apple", NULL));
if (!val.isEmpty) {
printf("apple 的数量: %d\n", *(int*)val.data);
freeSValInSChainMap(&map, &val);
}
// 判断存在
printf("\n是否存在 grape: %s\n",
hasSKeyInSChainMap(&map, Data_S_OWN("grape", NULL)) ? "是" : "否");
// 删除
printf("\n=== 删除数据 ===\n");
delSEntryBySKeyInSChainMap(&map, Data_S_OWN("banana", NULL));
printSChainMap(&map);
// 释放
freeSChainMap(&map);
return 0;
}