分享一下 哈希 luatable 索引值

博客主要分享哈希 LuaTable 索引值相关内容,虽未给出具体内容,但从标题可知围绕此信息技术点展开。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://www.xuebuyuan.com/2

原址:http://bbs.chinaunix.net/thread-3754752-1-1.html

分享一下对Lua的哈希表结构的研究。



    一般哈希表处理冲突有两种方式,拉链法和开放定址法。拉链法就是哈希表的每个元

素都是一个链表,如果有冲突的键就放在链表里面。而开放定址法是如果遇到了冲突,就

再计算一个哈希值,直到没有冲突位置。


    拉链法的优点就是实现简单,缺点也是有的:链表会导致低的缓存命中率,并且分配

链表节点本身也会对内存分配器产生压力(主要是大量小块内存分配会导致碎片),而且

有个更严重的问题:不大好估计哈希表的装载因子,因此不大容易判断啥时候需要扩充哈

希表。


    而开放定址法避免了这些问题,首先因为所有节点都存在哈希表里面,因此很容易就

能估计装载因子,其次也不会有内存分配的问题,避免了零散碎片或者实现内存池的必要

。不过问题是要找到一个新的地址就需要重新计算哈希,是一个负担,而且如果你在对应

哈希查找不到元素也可能并不是没有元素,而只是之前的冲突导致元素不在它的“主位置

”,这样就需要更多复杂的判断。


    解决主位置的问题其实很简单:可以设置一个“墓碑”,删除的时候并不是直接删除

,而是设置一个“墓碑”当发现是墓碑的时候,证明该位置曾经是有元素的,这时就按照

冲突的方式继续查找。总的来说,如果不考虑装载因子,因为要重复搜索哈希表,开放定

址法的查找是会比较慢的。


    Lua的哈希表其实我一直都不是特别明白,最近自己实现一个C版本的ninja的时候想

自己实现一个哈希表,就看了看Lua的实现,发现他居然是一个全新的思路!他将拉链法

和开放定址法结合在了一起。具体的做法是这样的:Lua的哈希表主体是开放定址法,即

所有元素都被存放在表中,而不是在链表里。但是,每个元素也的确有一个链表节点。在

开始的时候,Lua维护一个“空闲槽指针”这个指针之后的位置一定都是有元素的。当发

现冲突的时候,会将空闲槽指针前移,以找到一个空闲的槽位,然后元素会被放在这个槽

位里,并在主位置通过链表的方式链接进来!即对插入而言,Lua的哈希表采用的实际上

是不计算哈希的开放定址法(随意找一个槽位),而对于查找而言,因为有链表节点的存

在,是按照拉链法的方式进行查找的。这种方法利用了两者的优点,又规避了缺陷。

我的理解就是利用数组作为单链表 

    这里面其实还是有一些其他可以优化的地方。比如墓碑还是需要的,这用于在主位置

找不到以后,得得到后续节点的一个索引。但是通过在插入/删除节点时,挪动后续的节

点的方法,就可以省掉墓碑和对应的遍历操作。另外这种哈希表判断装载因子的方式也很

简单——只要空闲槽指针指向表的第一个元素,就意味着表已经满了,这时就需要rehash

了。


   

230054.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值