🔢 OAMap_S - 开放定址法哈希映射(单一数据类型)

采用开放定址法解决哈希冲突的键值对映射表,存储单一类型数据

📖 概述

OAMap_S (Open Addressing Map Single Data) 是一种采用开放定址法(Open Addressing)解决哈希冲突的 Map 数据结构。当发生冲突时,它会探测其他可用的槽位来存储数据。

📌 特点

  • 采用开放定址法处理哈希冲突
  • 内存利用率高,不需要额外的链表指针
  • 只能存储单一类型数据
  • 适合数据量较小、分布均匀的场景

💡 何时使用 OAMap vs ChainMap

  • 使用 OAMap: 数据量较小(<10000),数据分布均匀,可接受较高的负载因子
  • 使用 ChainMap: 数据量较大,分布不均匀,需要更稳定的查找性能

⚙️ 数据类型定义

// OAMap_S 中的 Entry 类型
typedef struct Entry_S_inOAMap {
    Data_S key;      // 键
    Data_S val;      // 值
    int state;       // 状态:存在/已删除/空
    bool isEmpty;    // 是否为空
} Entry_S_inOAMap;

// OAMap_S
typedef struct OAMap_S {
    Entry_S_inOAMap* arr;      // 哈希槽数组
    int mod;                    // 取模基数
    int len;                    // 槽位数量
    int size;                   // 元素数量
    InfoOfData* keyInfo;        // key 操作集
    InfoOfData* valInfo;        // value 操作集
} OAMap_S;

🚀 快速开始

#include "base.h"
#include "Map/OAMap/Single_Data/oamap_sdata.h"
#include "Oper/String_Info/string_info.h"
#include "Oper/Int_Info/int_info.h"

int main() {
    // 1. 初始化 Map
    OAMap_S map;
    initSOAMap(&map, &Info_String, &Info_Int);

    // 2. 插入键值对
    insertSkeyAndSValInSOAMap(&map, 
        Data_S_OWN("id", NULL), 
        Data_S_OWN(1001, NULL));

    insertSkeyAndSValInSOAMap(&map,
        Data_S_OWN("level", NULL),
        Data_S_OWN(99, NULL));

    // 3. 查找
    Data_S val = getCopySValBySkeyInSOAMap(&map, Data_S_OWN("id", NULL));
    if (!val.isEmpty) {
        printf("id: %d\n", *(int*)val.data);
    }

    // 4. 打印
    printSOAMap(&map);

    // 5. 释放
    freeSOAMap(&map);
    return 0;
}

📋 函数列表

🔧 初始化与销毁

void initSOAMap(OAMap_S* pMap, InfoOfData* keyInfo, InfoOfData* valInfo)

初始化 OAMap_S

参数:
  • pMap - OAMap_S 的指针
  • keyInfo - key 的 InfoOfData 类型指针
  • valInfo - val 的 InfoOfData 类型指针
void freeSValInSOAMap(OAMap_S* pMap, Data_S* inputData)

释放掉复制来的在 OAMap_S 中的 SVal

参数:
  • pMap - OAMap_S 的指针
  • inputData - SVal 类型指针 (Data_S 类型)
void freeSEntryInSOAMap(OAMap_S* pMap, Entry_S_inOAMap* entry)

释放掉复制来的在 OAMap_S 中的 SEntry (Entry_S_inOAMap 类型)

参数:
  • pMap - OAMap_S 的指针
  • entry - SEntry 类型 (Entry_S_inOAMap 类型)
void freeSOAMap(OAMap_S* pMap)

释放掉 OAMap_S

参数:
  • pMap - OAMap_S 的指针

➕ 插入与查询

InfoOfReturn insertSkeyAndSValInSOAMap(OAMap_S* pMap, Data_S key, Data_S val)

插入 key 和 val 到 OAMap_S 类型中去

参数:
  • pMap - OAMap_S 的指针
  • key - 传入的 key (Data_S 类型数据)
  • val - 传入的 val (Data_S 类型数据)
返回: 返回 InfoOfReturn 中的枚举类型
Data_S getCopySValBySkeyInSOAMap(OAMap_S* pMap, Data_S key)

通过 SKey 得到复制来的 SVal (Data_S 类型)

参数:
  • pMap - OAMap_S 的指针
  • key - 传入的 key (Data_S 类型数据)
返回: 返回 Data_S 类型数据,若没有返回空 Data_S 类型数据,通过 Data.isEmpty 进行查看
注意: 返回的数据使用后需要调用 freeSValInSOAMap 释放
Data_S getPtrSValBySKeyInSOAMap(OAMap_S* pMap, Data_S key)

通过 SKey 得到 SVal (Data_S 类型),可直接修改内部的 void* data 和 void* content 内容

参数:
  • pMap - OAMap_S 的指针
  • key - 传入的 key (Data_S 类型数据)
返回: 返回 Data_S 类型数据,若没有返回空 Data_S 类型数据,通过 Data.isEmpty 进行查看
警告: 返回的指针直接指向 Map 内部数据,请勿 free
Entry_S_inOAMap getCopySEntryByKeyInSOAMap(OAMap_S* pMap, Data_S key)

通过 SKey 得到复制来的 SEntry (Entry_S_inOAMap 类型)

参数:
  • pMap - OAMap_S 的指针
  • key - 传入的 key (Data_S 类型数据)
返回: 返回 Entry_S_inOAMap 类型数据,若没有返回空 Entry_S_inOAMap 类型数据,通过 entry.isEmpty 进行查看

🔍 判存与删除

bool hasSKeyInSOAMap(OAMap_S* pMap, Data_S key)

判断 Skey 是否在 OAMap_S 中

参数:
  • pMap - OAMap_S 的指针
  • key - 传入的 key (Data_S 类型数据)
返回: 如果存在返回 true,否则返回 false
InfoOfReturn delSEntryBySKeyInSOAMap(OAMap_S* pMap, Data_S key)

通过 SKey 删除在 OAMap_S 中的元素

参数:
  • pMap - OAMap_S 的指针
  • key - 传入的 key (Data_S 类型数据)
返回: 返回 InfoOfReturn 中的枚举类型

🖨️ 打印

void printSOAMap(OAMap_S* pMap)

打印 OAMap_S 中的所有数据

参数:
  • pMap - OAMap_S 的指针
void printSKeyInSOAMap(OAMap_S* pMap, Data_S keyData)

打印在 OAMap_S 中的 SKey (Data_S 类型)

参数:
  • pMap - OAMap_S 的指针
  • keyData - SKey (Data_S 类型)
void printSValInSOAMap(OAMap_S* pMap, Data_S valData)

打印在 OAMap_S 中的 SVal (Data_S 类型)

参数:
  • pMap - OAMap_S 的指针
  • valData - SVal (Data_S 类型)
void printSEntryInSOAMap(OAMap_S* pMap, Entry_S_inOAMap entry)

打印在 OAMap_S 中的 SEntry (Entry_S_inOAMap 类型)

参数:
  • pMap - OAMap_S 的指针
  • entry - SEntry (Entry_S_inOAMap 类型)

💡 完整示例

#include <stdio.h>
#include "base.h"
#include "Map/OAMap/Single_Data/oamap_sdata.h"
#include "Oper/String_Info/string_info.h"
#include "Oper/Int_Info/int_info.h"

int main() {
    // 初始化 Map
    OAMap_S map;
    initSOAMap(&map, &Info_String, &Info_Int);

    // 插入数据
    printf("=== 插入数据 ===\n");
    insertSkeyAndSValInSOAMap(&map, 
        Data_S_OWN("name", NULL), 
        Data_S_OWN(1, NULL));
    insertSkeyAndSValInSOAMap(&map, 
        Data_S_OWN("age", NULL), 
        Data_S_OWN(25, NULL));
    insertSkeyAndSValInSOAMap(&map, 
        Data_S_OWN("city", NULL), 
        Data_S_OWN(3, NULL));

    printSOAMap(&map);

    // 查询
    printf("\n=== 查询数据 ===\n");
    Data_S val = getCopySValBySkeyInSOAMap(&map, Data_S_OWN("age", NULL));
    if (!val.isEmpty) {
        printf("age: %d\n", *(int*)val.data);
        freeSValInSOAMap(&map, &val);
    }

    // 判断存在
    printf("\n是否存在 country: %s\n", 
        hasSKeyInSOAMap(&map, Data_S_OWN("country", NULL)) ? "是" : "否");

    // 删除
    printf("\n=== 删除数据 ===\n");
    delSEntryBySKeyInSOAMap(&map, Data_S_OWN("city", NULL));
    printSOAMap(&map);

    // 释放
    freeSOAMap(&map);
    return 0;
}

⚠️ 注意事项