http://bannalia.blogspot.tw/2013/10/implementation-of-c-unordered_25.html
上次我們介紹了Hash Table各種流行的方法,現在我們來考慮如果元素有重複,要怎麼辦?
(unordered_multiset , unordered_multimap)
Hash Table跟重複元素,這是兩個不同玩意,不要混在一起。兩個基本問題要解決。
- Hash的負載係數(load factor)是[所有元素]除以[所有桶子],但因為重複元素會放在同一個桶子。必須要重新設計負載係數,不然陣列會拼命長大,結果大多數桶子都是空 的。
- 演算法複雜度跟負載係數無關,而是跟桶子裡面塞了多少東西有關。
- Dinkumware libc++ , libstdec++ -V3函式庫
- Boost.Unordered
桶子b2裡面有五個相同的元素。往前指的指標改成指向重複元素最後一個。利用這個反向指標,可以把五個元素視為一個大節點。插入或刪除的時候,先找到第一 個元素,利用反向指標直接跳到第五個元素。省去了掃描的麻煩。
- Boost.MultiIndex
定一個節點叫做X,下一個節點叫做Xn,前一個節點叫做Xp。
假設有多個元素重複,全部串在一起。
第一個叫做F
第二個叫做S
倒數第二個叫做P
倒數第一個叫做L
- Sp=L
- Pn=F
倒數第二個元素,[往後指標]會指向最初節點。
推導一些特性
- 如果Xpnn == X,那就是桶子第一個節點
- 如果Xnpn == X,那就是桶子最後節點
- 如果相同元素>=3,串成一個集團,集團第一個節點條件是Xnp != X && Xnppn == X
- 如果相同元素>=3,串成一個集團,集團第二個節點條件是Xpn != X && Xppnn == X
- 如果相同元素>=3,串成一個集團,集團倒數第二個節點條件是Xnp != X && Xnnpp == X
- 如果相同元素>=3,串成一個集團,集團倒數第一個節點條件是Xpn != X && Xpnnp == X
插入元素的方法:
- 使用Hash先找到桶子。(常數時間)
- 檢查桶子裡面的每個元素,遇到集團的時候,只要檢查集團第一個節點即可。(桶子大小線性時間)
- 如果元素等於某個集團,把元素加入集團內。如果整個桶子沒有相同元素,直接插入在桶子的頭端。
- 調整桶子的指標。
刪除元素的方法:
- 刪除鏈結裡面的元素,調整前後指標。
- 調整桶子的指標。
沒有留言:
張貼留言