Lua的雜湊表結構

2021-06-26 18:07:19 字數 1378 閱讀 8380

原址:

分享一下對lua的雜湊表結構的研究。

一般雜湊表處理衝突有兩種方式,拉鍊法和開放定址法。拉鍊法就是雜湊表的每個元

素都是乙個鍊錶,如果有衝突的鍵就放在鍊錶裡面。而開放定址法是如果遇到了衝突,就

再計算乙個雜湊值,直到沒有衝突位置。

拉鍊法的優點就是實現簡單,缺點也是有的:鍊錶會導致低的快取命中率,並且分配

鍊錶節點本身也會對記憶體分配器產生壓力(主要是大量小塊記憶體分配會導致碎片),而且

有個更嚴重的問題:不大好估計雜湊表的裝載因子,因此不大容易判斷啥時候需要擴充哈

希表。而開放定址法避免了這些問題,首先因為所有節點都存在雜湊表裡面,因此很容易就

能估計裝載因子,其次也不會有記憶體分配的問題,避免了零散碎片或者實現記憶體池的必要

。不過問題是要找到乙個新的位址就需要重新計算雜湊,是乙個負擔,而且如果你在對應

雜湊查詢不到元素也可能並不是沒有元素,而只是之前的衝突導致元素不在它的「主位置

」,這樣就需要更多複雜的判斷。

解決主位置的問題其實很簡單:可以設定乙個「墓碑」,刪除的時候並不是直接刪除

,而是設定乙個「墓碑」當發現是墓碑的時候,證明該位置曾經是有元素的,這時就按照

衝突的方式繼續查詢。總的來說,如果不考慮裝載因子,因為要重複搜尋雜湊表,開放定

址法的查詢是會比較慢的。

lua的雜湊表其實我一直都不是特別明白,最近自己實現乙個c版本的ninja的時候想

自己實現乙個雜湊表,就看了看lua的實現,發現他居然是乙個全新的思路!他將拉鍊法

和開放定址法結合在了一起。具體的做法是這樣的:lua的雜湊表主體是開放定址法,即

所有元素都被存放在表中,而不是在煉表裡。但是,每個元素也的確有乙個鍊錶節點。在

開始的時候,lua維護乙個「空閒槽指標」這個指標之後的位置一定都是有元素的。當發

現衝突的時候,會將空閒槽指標前移,以找到乙個空閒的槽位,然後元素會被放在這個槽

位里,並在主位置通過鍊錶的方式鏈結進來!即對插入而言,lua的雜湊表採用的實際上

是不計算雜湊的開放定址法(隨意找乙個槽位),而對於查詢而言,因為有鍊錶節點的存

在,是按照拉鍊法的方式進行查詢的。這種方法利用了兩者的優點,又規避了缺陷。

我的理解就是利用陣列作為單鏈表 

這裡面其實還是有一些其他可以優化的地方。比如墓碑還是需要的,這用於在主位置

找不到以後,得得到後續節點的乙個索引。但是通過在插入/刪除節點時,挪動後續的節

點的方法,就可以省掉墓碑和對應的遍歷操作。另外這種雜湊表判斷裝載因子的方式也很

簡單——只要空閒槽指標指向表的第乙個元素,就意味著表已經滿了,這時就需要rehash

了。

資料結構 雜湊表(雜湊表)hash table

hash table 在計算機中,雜湊表 是 一種實現了關聯陣列 抽象資料型別的資料結構,這種資料結構可以對映 鍵 key 和 值 value 補充 關聯陣列 在電腦科學中,乙個關聯陣列 associative array 對映 map 符號表 symbol table 或者是字典 dictiona...

資料結構 雜湊表 雜湊表 原理

記錄的儲存位置 f 關鍵字 這裡的對應關係f稱為雜湊函式,又稱為雜湊 hash函式 採用雜湊技術將記錄儲存在一塊連續的儲存空間中,這塊連續儲存空間稱為雜湊表或雜湊表 hash table 雜湊表hashtable key,value 就是把key通過乙個固定的演算法函式既所謂的雜湊函式轉換成乙個整型...

資料結構 雜湊表查詢(雜湊表)

對於查詢,有順序表直接遍歷,有折半查詢直到查詢成功。但是這都需要不斷的比較,每一次查詢都需要重新遍歷,所以當資料龐大時是非常耗時的。雜湊表是一種可以避免多次比較,直接通過關鍵字就可以得到要查詢的記錄記憶體儲存位置。例如就像是乙個函式,每乙個自變數都對應著乙個函式值,即 這屬於雜湊技術,不需要比較就可...