07_Radis-dict(字典)

一:字典序结构定义

在这里插入图片描述

1.字典条目设计:

typedef struct dictEntry
{
    void* key;
    void* val;
    struct dictEntry* next;
}dictEntry;

在这里插入图片描述

2.哈希表的设计:

typedef struct dictht
{
    // 哈希表节点指针数组(俗称桶,bucket)
    dictEntry** table;
    // 指针数组的大小 标识dictEntry指针数组的长度。它总是2的指数次幂。
    unsigned long size;  // 4  // 8   // 16
    // 指针数组的长度掩码,
    //用于计算索引值 用于将哈希值映射到table的位置索引。
    //它的值等于(size-1),比如3,7, 15, 31, 63,等等,
// 3 0000 0011 // 7 0000 0111  // 15 // 0000 1111  
//当给定任意一个整数与15相与都能保证前4位都为0,因此与后的数值范围都在0到15之间,从而确定放在table哪个下标之下
    //也就是用二进制表示的各个bit全1的数字。
    //每个key先经过hashFunction计算得到一个哈希值,
    //然后计算(哈希值 & sizemask)得到在table上的位置。相当于计算取余(哈希值 % size)。
    unsigned long sizemask; 
    // 哈希表现有的节点数量
    //记录dict中现有的数据个数。
    //它与size的比值就是装载因子。这个比值越大,哈希值冲突概率越高。
    unsigned long used;//used的值大于size,比值大于1就需要扩容
} dictht;

在这里插入图片描述

3.字典的设计:

typedef struct dict
{
    // 特定于类型的处理函数
    dictType* type;
    // 类型处理函数的私有数据
    void* privdata;
    // 哈希表    只有在rehash的过程中,ht[0]和ht[1]才都有效。
    //而在平常情况下,只有ht[0]有效,ht[1]里面没有任何数据。
    dictht ht[2];
    // 记录 rehash 进度的标志,值为 -1 表示 rehash 未进行
    //标识是否需要重置哈希(步进式增容)
    int rehashidx; /* rehashing not in progress if rehashidx == -1 */
    // 当前正在运作的安全迭代器数量
    int iterators; /* number of iterators currently running */
} dict;

在这里插入图片描述

4.table指向的数组

dictEntry** table;

该结构是通过malloc()在堆区开辟连续空间,连续空间的类型是字典条目的一级指针,table指向该连续空间
在这里插入图片描述

5.处理数据类型的结构

由于字典条码的key可能是整型,可能是字符串…哈希表并不认识这些数据,因此就需要对用户输入的数据进行识别,翻译成哈希表认识的字典类型

typedef struct dictType
{
    // 对key进行哈希值计算的哈希算法
    unsigned int (*hashFunction)(const void* key);
    //分别定义key和value的拷贝函数, 用于在需要的时候对key和value进行深拷贝,而不仅仅是传递对象指针。  
    void* (*keyDup)(void* privdata, const void* key);
    void* (*valDup)(void* privdata, const void* obj);
    //定义两个key的比较操作,在根据key进行查找时会用到。
    int (*keyCompare)(void* privdata, const void* key1, const void* key2);
    // Destructor 析构函数
    void (*keyDestructor)(void* privdata, void* key);
    void (*valDestructor)(void* privdata, void* obj);
} dictType;

二.建立并初始化字典

1.创建字典

在这里插入图片描述

dict* dictCreate(dictType* type, void* privDataPtr)
{
   // dict* d = (dict*)malloc(sizeof(*d));
    dict* d = (dict*)malloc(sizeof(dict));
    if (d != NULL)
    {
        _dictInit(d, type, privDataPtr);
    }
    return d;
}

2.初始化字典

static int _dictInit(dict* d, dictType* type, void* privDataPtr)
{
    _dictReset(&d->ht[0]);
    _dictReset(&d->ht[1]);
    d->type = type;
    d->privdata = privDataPtr;
    d->rehashidx = -1;  // -1 no rehash // 
    d->iterators = 0;
    return DICT_OK;
}

3.设置数组

static void _dictReset(dictht* ht)
{
    ht->table = NULL;
    ht->size = 0;
    ht->sizemask = 0;
    ht->used = 0;
}
//斜杠都是宏的链接符,注意:斜杠后紧接着就是回车,不能出现任何符号
//将这个宏放在do while {}循环里目的是防止宏被多次引入后只执行一次
#define dictSetHashVal(d, entry, _val_) do { \
    if ((d)->type->valDup) \
        entry->val = (d)->type->valDup((d)->privdata, _val_); \
    else \
        entry->val = (_val_); \
} while(0)
#define PE do\
		{\
		printf("xsyhello !\n");\
		} while (0);

int main()
{
	for (int i = 0;i < 10;++i)
	{
		PE;
	}
	return 0;
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值