hashmap 设计

先来看看泛型的数据队列。
自然界中的数据关系多分为两种,拿人类来看,一类是靠人与人之间的关系来互相关联,我称为关系型,另一种是靠屁股相互关联,我称为位置型。
对于关系型,一个富豪家族,女屌丝想成为其中成员很简单,与其中一个老头建立夫妻关系就加入了这个家族,被虐待了后想脱离它也很简单,解除夫妻关系就完事了。
再看看位置型,比如厕所里有20个坑,上面都贴上数字,有人报告第17个坑堵了,找起来会很方便。再比如某市一个市有20个市长,内部等级顺序都分好了的,在一次内部会议合影时要排序,摄影员喊一声第14位的拉链开了,第14位市长马上就什么知道是自己。
这两种类型的优点都出来了:
关系型:插入,删除成员方便。
位置型:查找方便。

并不是报喜不报忧,对方的优点就是已方的缺点,反之,已方的优点就是对方的缺点,大自然是很奇秒的。

人类最大的创新就是学习和模拟大自然,因为大自然没有申请专利保护。飞机是模彷鸟类,潜艇是模彷鱼类,程序员也要模彷,于是便有了我们的数组和链表,分别对应位置型和关系型。
在标准库里,分别是 vector和 list.
vector 是分配一段连续的内存块,一块一块的被填充,当填充完的时候,就整个重新分配,并把数据迁移过去,就像那些富豪家族在国内发展不了了,整个搬迁米国。
list 来一个分配一个,建立关系,走一个释放一个。

vector,list 不是基于 key-value 型的,要把它封装才能被当作缓存。
于是便有了前文提到的红黑树和本文的主角hash map.
红黑树的思想是关系型的,不过关系复杂点,模彷的更像点,有了父亲,左孩子,右孩子的概念,其实理解成儿子和女儿又有何不可呢。
hash map 自然就是基本位置型的了。

那么hash map的工作原理是什么呢?
从名字上就可以看出来,新数据插入和查找都要经过两步:
1.hash,就是散列。
2.map,就是存储映射。

那么为什么要散列呢,一切都是为了找位置,明白了么,就像那么多副市长,是怎么排序的,可以靠体型,也可以靠体重,散列的方法有很多种。
比如两个字符串key: 
1.hello
2.world

如何才能快速的定位到哪个位置呢,可以把以首字母的ascii码为key, 就能快速存储和快速查找了。hello 对应的是104, world 对应的是119.
hello 104
world 119

建立了一个对应表,既是hash表,也是map表。
再复杂一点,比如有下面的场景:
1.hello
2.hello world
3.world

第1种和第2种如何区别呢,共同对应104位,这个问题在学术上叫散列冲突,比如恰好有两个副市长的体重一样。

下面看看我是怎么设计hash map的

typedef struct yumei_hash_map_s yumei_hash_map_t;
typedef struct yumei_cache_data_s yumei_cache_data_t;

struct yumei_hash_map_s
{
	int  reserve;
	yumei_cache_data_t*   data;

};

struct yumei_cache_map_data_s
{
	int key;
	int times;
	int start_time;

	void*  data;

	yumei_cache_map_data_t* next;
};

yumei_hash_map_t*   yumei_hash_map_create();
int yumei_hash_map_release( yumei_hash_map_t* hm );

int yumei_hash_map_insert( yumei_hash_map_t* hm, int key, void* data );
int yumei_hash_map_get( yumei_hash_map_t* hm, int key, void** data );
int yumei_hash_map_check( yumei_hash_map_t* hm );
int yumei_hash_map_update( yumei_hash_map_t* hm, int key, void* data );

整个框架就搭起来了,核心是散列和冲突的解决。
散列算法:
int kv = key &( reserve - 1 );

冲突解决:
while( tmp ){
	if( tmp->key == key ){
		break;
	}

	tmp = tmp->next;
}

data = tmp->data;

其实是在同一个位置上多挂几个,就像一个市长位置上有几个候选人,散列以后再来比对,这是最简单有效的方法,当然如果需要在挂列上再进行排列或者特殊场景下的二次散列可能效果更好。

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值