hash,也可以稱為「雜湊」,就是把任意長度的輸入,通過雜湊演算法,變換成固定長度的輸出,該輸出就是雜湊值。這是一種壓縮對映,也就是,雜湊值的空間通常遠小於輸入的空間,不同的輸入可能會雜湊成相同的輸出(也就是多對一的關係)。
在所有的線性資料結構中,陣列的定位速度最快,因為它可通過陣列下標直接定位到相應的陣列空間,就不需要乙個個查詢。而雜湊表就是利用陣列這個能夠快速定位資料的結構解決以上的問題的。
"陣列可以通過下標直接定位到相應的空間」,對就是這句,雜湊表的做法其實很簡單,就是把key通過一 個固定的演算法函式既所謂的雜湊函式轉換成乙個整型數字,然後就將該數字對陣列長度進行取餘,取餘結果就當作陣列的下標,將value儲存在以該數字為下標 的陣列空間裡,而當使用雜湊表進行查詢的時候,就是再次使用雜湊函式將key轉換為對應的陣列下標,並定位到該空間獲取value,如此一來,就可以充分 利用到陣列的定位效能進行資料定位。
通過關鍵字除以槽數m將關鍵字對映到槽裡的方法。雜湊函式是h(k)=k mod m。
舉個例子,m=12,k=100,h(100)=4。
而如果m=2k,那麼無論k是什麼,h(k)的值都是乙個0和奇數,也即是說只要奇數槽和0槽被占用,其他的偶數槽都是浪費掉了。如果m=2^r,那麼h(k)的值就是k的低r位(化成二進位制)。這樣造成的後果是某乙個槽有很多的關鍵字。所以來說一般的m取值盡量不要接近2的整數冪,而且還要是質數。
快速查詢,刪除的基本資料結構,通常需要總資料量可以放入記憶體。
map是c++標準庫stl提供的一類關聯式容器,提供key-value的儲存和查詢功能。
map是基於紅黑樹的(同樣set也是),那麼它的查詢速度是log(n)級別的。
它的優點是占用記憶體小。
權衡三個因素: 查詢速度, 資料量, 記憶體使用,可擴充套件性,有序性。
總體來說,hash查詢速度會比rb樹快,而且查詢速度基本和資料量大小無關,屬於常數級別;而rb樹的查詢速度是log(n)級別。並不一定常數就比log(n) 小,因為hash還有hash函式的耗時。當元素達到一定數量級時,考慮hash。但若你對記憶體使用特別嚴格, 希望程式盡可能少消耗記憶體,那麼hash可能會讓你陷入尷尬,特別是當你的hash物件特別多時,你就更無法控制了,而且 hash的構造速度較慢。
紅黑樹並不適應所有應用樹的領域。如果資料基本上是靜態的,那麼讓他們待在他們能夠插入,並且不影響平衡的地方會具有更好的效能。如果資料完全是靜態的,例如,做乙個雜湊表,效能可能會更好一些。
在實際的系統中,例如,需要使用動態規則的防火牆系統,使用紅黑樹而不是雜湊表被實踐證明具有更好的伸縮性。linux核心在管理vm_area_struct時就是採用了紅黑樹來維護記憶體塊的。
總結:
紅黑樹是有序的,hash是無序的,根據需求來選擇。
紅黑樹占用的記憶體更小(僅需要為其存在的節點分配記憶體),而hash事先就應該分配足夠的記憶體儲存雜湊表(即使有些槽可能遭棄用)。
紅黑樹查詢和刪除的時間複雜度都是o(logn),hash查詢和刪除的時間複雜度都是o(1)。
補充:
如果只需要判斷map中某個值是否存在之類的操作,當然是hash實現的要更加高效。
如果是需要將兩個map求並集交集差集等大量比較操作,就是紅黑樹實現的map更加高效。
關於紅黑樹的介紹,發現一篇文**並茂的文章
多讀兩遍,相信會有不小的收穫
雜湊表和紅黑樹
hash,也可以稱為 雜湊 就是把任意長度的輸入,通過雜湊演算法,變換成固定長度的輸出,該輸出就是雜湊值。這是一種壓縮對映,也就是,雜湊值的空間通常遠小於輸入的空間,不同的輸入可能會雜湊成相同的輸出 也就是多對一的關係 在所有的線性資料結構中,陣列的定位速度最快,因為它可通過陣列下標直接定位到相應的...
紅黑樹的特點
紅黑樹本質上是一顆自平衡的二叉樹 a.每乙個節點非紅即黑 b.根節點一定是黑節點 c.紅節點下一定是黑節點,但黑節點下可以是紅節點,也可以是黑節點 d.最頂層的葉子節點一定是黑色的空節點 e.任意一條路徑經過的黑節點個數一致,即黑節點高度一致 f.新新增的子節點一定是紅節點 修正過程 1 當前節點為...
雜湊表和紅黑樹的對比
hash,也可以稱為 雜湊 就是把任意長度的輸入,通過雜湊演算法,變換成固定長度的輸出,該輸出就是雜湊值。這是一種壓縮對映,也就是,雜湊值的空間通常遠小於輸入的空間,不同的輸入可能會雜湊成相同的輸出 也就是多對一的關係 在所有的線性資料結構中,陣列的定位速度最快,因為它可通過陣列下標直接定位到相應的...