本身寫一個 Hash 表

項目地址:  https://github.com/kelin-xycs/HashTableLibhtml

 

爲何會想要本身寫一個 Hash 表, 之前也想過 Hash 表 的 原理, 以爲很神奇,git

不過最近的 直接緣由 是 最近在搞  ILBC, 這能夠認爲是一個 編譯器 項目,github

有關 ILBC,  見 《ILBC 規範》  http://www.javashuo.com/article/p-hsmtjoox-s.html ,數組

 

編譯器 裏 會 須要 快速 的 查找 成員(變量 、字段 、類 、 方法 / 函數),  好比 檢驗 成員 是否重名, 以及 對 成員 的 訪問 的 編譯工做 。函數

也包括 運行期查找成員(反射 / 動態連接)  。性能

 

固然 ILBC 裏使用的 Hash 表 會用 C 語言 寫, 此次寫的 項目 是 用 C# 寫的, 在 原理 上 實現了一下 。spa

 

具體的邏輯 看代碼 就行, 代碼很少, 大約 350 行 。  ^^設計

不過有一點說明一下, 就是能夠調用 HashTable 的 htm

 

public HashTable(int initCapacity)blog

 

這個 構造函數 重載 來 指定    initCapacity ,

 

也能夠調用

 

public HashTable(int initCapacity, double whenEnlarge, double enlargeRatio)

 

這個 構造函數 重載 來 指定    initCapacity,  whenEnlarge,  enlargeRatio ,

 

initCapacity  表示 new HashTable  時 的 初始 的 Hash 表 容量,  容量 是指 Hash 表 內部 存儲元素 的 數組 的 長度,

whenEnlarge  表示 當 元素(鍵值對) 的 數量 達到  容量 的 百分之幾 時, 要對 Hash 表 擴容(增大容量), 擴容 就是 按照 新的 容量 申請一個 數組, 把 原來的 數組 的 元素 從新 添加到 新數組 裏, 注意 這裏的 添加 不是 簡單的複製, 而是 把  元素(鍵值對) 從新 添加(Add) 到 Hash 表, 在 添加(Add) 時 會 從新計算 key 的 Hash 值 並 根據 key 的 Hash 值 計算 鍵值對 在 數組 裏的 位置(下標 ( index )) 。

enlargeRatio  表示 擴容 時 要 擴大多少, 即 增長的容量 相對於 原來的容量 所佔 的 百分比 。

 

若是不想本身指定   initCapacity,  whenEnlarge,  enlargeRatio ,    也能夠調用 無參 構造函數

 

public HashTable()

 

無參 構造函數 使用 默認的   initCapacity,  whenEnlarge,  enlargeRatio ,

initCapacity 的 默認值 是 100 ,

whenEnlarge 的 默認值 是 0.8 ,

enlargeRatio 的 默認值 是 0.3  。

 

若是 知道 元素(鍵值對) 的 數量 或者 大概數量, 能夠 指定  InitCapacity ,  這樣能夠 避免 或 減小 擴容 , 提升效率 。

注意 若是 指定 Capacity 是 100,  whenEnlarge 是 0.8, 那麼 當 元素(鍵值對) 數量 達到  100 * 0.8 = 80  後, 再 添加 鍵值對 時, 就會 擴容 。

 

如今的設計 只涉及到 擴容, 沒有 「縮容」,  縮容 是指 當 元素(鍵值對) 數量 減小到 必定程度 時, 會 減小 Capacity ,  把 元素(鍵值對) 放到一個 長度更小 的 數組 裏  。

縮容 的 部分 能夠仿照 擴容 來寫,   但要注意  whenDeLarge 和 whenEnlarge  之間 應該要有 顯著 的 差距,  若是 二者 相等 或者 相近,  可能會  剛 擴容 又 縮容,  剛 縮容 又 擴容,  頻繁 擴容 縮容 致使 性能低下  。

不過 通常場合 好像 不須要 縮容  。

相關文章
相關標籤/搜索