• 沒有找到結果。

Michael Tsai2010/12/24 HASHING

N/A
N/A
Protected

Academic year: 2022

Share "Michael Tsai2010/12/24 HASHING"

Copied!
33
0
0

加載中.... (立即查看全文)

全文

(1)

HASHING

Michael Tsai

2010/12/24

(2)

提早下課 !

作業五期限延長至週四下午五點

期末將近 , 請各位同學注意身體健康 ( 該封電動了 )

補課時間請班代利用提早下課時間調查後通知我

( 原則上以下周為主 )

(3)

Outline

上次未解決的一些問題

Sorting on several keys & radix sort

Static hashing

Dynamic hashing

(4)

上次未解決的問題 (1)

Non-comparison sorting time complexity

電話排序問題

假設全部電話號碼有 s 個種可能 ( 所有排列組合 )

我們有 n 組電話要排

則使用超大表格排序法需要 O(s)

如果使用 comparison-based sorting 平均需要

假設超大表格排序法所需時間為

假設 comparison-based 排序法所需時間為

break even point 為 s= 10 n log n

假設以台北市電話號碼為例 ,

, n<

break even point 大約為 n=k

當 n 大於此數則 non-comparison sorting 比較快

•  

(5)

上次未解決的問題 (2)

問 : 如果我們使用 linked list representation 來做 mer ge sort ( 而不是用 array), 我們還需要另外一個跟 n 一 樣大小的地方來存資料嗎 ?

答案 : 不需要

參閱 : http://www.chiark.greenend.org.uk/~

sgtatham/algorithms/listsort.html

但是如果原本資料是放在 array, 還是需要一些額外的空 間 ( 做 linked list)

(6)

Sorting on several keys

假設 K 有很多個 sub-key

則 iff

for some , or

則我們可以有以下的 sorting 方法 .

先依照 most significant key sort, 然後依序往 least significan t key sort 過去 : Most Significant Digit first (MSD) sorting

先依照 least significant key sort, 然後依序往 most significan t key sort 過去 : Least Significant Digit first (LSD) sorting

•  

6

Most significant key Least significant key

(7)

Sorting on several keys

哪一種比較好 ?

如果使用 stable sorting algorithm, 則 LSD sort 比較 單純

sort 成”一桶一桶”以後不需要分開 sort

用黑板舉例吧 ~~ ( 投影片做到發瘋了 )

7

(8)

Radix Sort

方法 : 每次用某種方法把 items 分為 r 堆 . 然後再 concaten ate 起來 .

怎麼分為 r 堆 ?

舉例 : 每次使用某一位數的數字分堆 .

第一次依照個位數分為十堆 , 然後再放在一起 .

第二次依照十位數分為十堆 , 然後再放在一起 .

直到完成 ( 共 d 個 pass).

最後放在一起的 items 即為 sort 好的 list.

用黑板舉例 .

•  

8

(9)

有沒有一種天方夜壇

神秘的資料結構 Insert

Search

Delete

=O(1)

Hint: “ 以空間換取時間”

(key, data)

(10)

概念

很多很多有編號的櫃子

問 : “ 菜瓜布”的資料去哪找 ? (“ 菜瓜布” , 資料 )

管理員 : “ 菜瓜布” 對 應到 1028 號櫃子

1028 管理員

如果箱子夠多 , 則花費在一個箱子裡面尋找的時間 =O(1)

(11)

概念

很多很多有編號的櫃子

問 : “ 菜瓜布”的資料去哪找 ?

管理員 : “ 菜瓜布” 對 應到 1028 號櫃子

1028 管理員

Hash function:

h(k)

Hash table

櫃子數目 : b

每個位子可以放的資料數 :s

sb: 所有可以放數櫃子資料數目 key: 拿來當索引的東西

例如 : “ 菜瓜布”

T: 所有可能的 key 的數目 n: 所有要存入的 pair 的數目

Key density: n/T

loading density: n/sb

(12)

一些定義

h(k): hash function

hash function 把 key 對應到一個數值 ( 通常為櫃子數 目 )

有可能把不同的 key 對應到同一個數值

( 但是沒關係 )

如果 , 則 are synonyms with respect to .

collision: 要把資料存進某櫃子的時候 , 該櫃子已經有 東西了

overflow: 要把資料存進某櫃子的時候 , 該櫃子已經滿了

if s==1, 則每次 collision 都會造成 overflow

•  

(13)

為什麼是 O(1)

當沒有 overflow 的時候 :

計算 hash function 的時間 : O(1)

進到某一個櫃子去 insert, delete, search 的時間都是 O (1)

worst case 為尋找 s 個空間的時間 : 固定

所以為 O(1)

剩下的問題 :

(1) 怎麼 implement 一個好的 hash function?

(2) 當 overflow 發生的時候怎麼處理 ?

(14)

Hash function

先要知道的事情 :

不可能讓所有 key 都 map 到不同的櫃子

( 因為通常 K 遠大於櫃子數目 )

目標 :

(1) 希望隨便取一個 key, 則平均來說它存到任何一個櫃 子的機率都是 1/b (b 為櫃子數目 ) ( 都是一樣的 )

(2) 計算 hash function 的時間為 O(1)

當 (1) 符合時 , 此 hash function 稱為 uniform hash fun ction

(15)

一些 hash function 的例子

複習 : h(k) 把 k 轉成另外一個數字 ( 櫃子編號 )

(1) Division: h(k)=k%D

則結果為 0 ~ D-1 通常我們可以把 D 設為櫃子數目

(2) Mid-square: h(k)=

則結果為 0 ~ , 所以通常櫃子數目為

•  

(16)

一些 hash function 的例子

(3) shift folding

用例子解釋 :

k=12320324111220

每隔幾位數切一份 . 例如 , 三位數 : ( 櫃子有 1000 個 )

{123, 203, 241, 112, 20}

h(k)=(123+203+241+112+20)%1000=699

(4)folding at the boundaries

{123,302,142,211,20}

h(k)=(123+302+142+211+20)%1000=897

(17)

一些 hash function 的例子

(5) digit analysis

假設先知道所有的 key 了

此時就可以尋找一個比較好的 hash function

假設 k 有 5 位數 , 我們有 100 個櫃子

則需要把 5 位數轉換成 2 位數

則我們可以每次選某一位數來分類成 10 組

最不平均的 3 個位數可以刪掉

( 記得一開始說 , 最好可以使得分到某櫃子的機率都相 等 )

(18)

Key 是 string 怎麼辦 ?

• 轉成數字 ! ( 然後再使用 hash function)

• 可不可以把不同字串轉成一樣數字 ?

• 答 : 可以 ! 反正 hash function 一樣已經會把不同 key 轉 成一樣的櫃子號碼了

• 方法 :

• (1) 把所有字串的 character( 數字 ) 加起來 , 進位的通通 丟掉 . ( 類似 checksum)

• (2) 把所有字串的 character ( 數字 ) 分別往左位移 i 格 , i 為該 character 在字串中的位置 , 然後通通加起來 .

• 舉例

(19)

Overflow 處理

兩種常用處理 overflow 的方法 :

(1) Open addressing

Full!

Find another empty cabinet

(2) Chaining

Full!

多出來的吊在下面 注意 : 要確保能夠下次也能找到同一個地方 !

(20)

Open addressing – Linear probing

有好幾種方法 :

(1) Linear probing

ht[(h(k)+1)%b], ht[(h(k)+2)%b], …

insert 的時候順著往下找 :

一直找到

a. 有空位 填入

b. 回到原來的位置 h(k) 了 , 則沒有空位可能要擴大 .

search 的時候 , 一樣是從 ht[h(k)] 開始往下找 , 一直找到

a. 有空位 k 不在 table 裡

b. 找到了 , k 在 ht[(h(k)+j)%b] 的位置

c. 回到原本的位置 h(k) 了 , k 不在 table 裡面

(21)

Open addressing – Linear probing

有沒有什麼壞處 ?

尋找 overflow 出去的 element 需要花額外的時間 ( 不是 O (1) 了 )

linear probing 讓在櫃子裏面的 key 容易集結在一起 ( 平 均尋找時間更長 )

想想看為什麼

(22)

Open addressing – 其他方法

其他方法 :

(2)quadratic probing

b 為一 prime number, 為 4j+3 之形式 ( 如 , 3, 7, 11, 1 9, …)

(3)rehashing

準備 m 個 hash function:

依序尋找

•  

(23)

來做一些分析 ( 沒有推導 )

Expected average number of key comparisons when looki ng up a key

尋找一個 key 時平均所需比較的 key 個數

因為其他的 operation 都只需要 O(1), 所以這個動作決定了 search 的 time complexity

失敗 ( 找到空位 ):

成功 :

Worst case?

全部都連在一起 , 全部都填滿了

O(n)

•  

(24)

Chaining

之前的方法的缺點 ?

尋找過程中 , 需多其他的資料的 hash 值 和現在要找的 key k 的 hash 值根本就不一 樣

有點冤枉

所以採取”掛勾”的方法

每個櫃子是一個 linked list

搜尋的時候只會找掛在下面的 (h(k) 都 一樣 )

Not here

結果在這邊 Not here

Not here

(25)

Chaining – Worst case

Worst case:

全部都塞在同一個櫃子下面的 linked list

time complexity 這樣是 ?

O(n)

小小的進步 : 底下可以用 binary search tree( 之後有 ba lanced 版 )

可以進步到

•  

(26)

Chaining - Expected performance

每個櫃子的 chain 上面平均有幾個 pair?

n: 總共存入的資料 pair 數目

b: 櫃子數目

所以假設使用 uniform hash function 的話

平均一個 chain 有 n/b 個 pair ( 個 pair)

這也是如果找不到的話 , 平均需要比較的次數

如果找得到的話 , 平均需要找 chain 上面一半的 pair 數 目加上一次 ( 找到那個 pair 時所做的比較 )

也就是說 ,

•  

(27)

Dynamic hashing

觀察 : 當 n/b 比較大以後 , O(1) 就開始崩壞 ( 往 O(n) 方向移 動 )

應變 : 所以要隨時觀察 n/b, 當它大過某一個 threshold 時就 把 hash table 變大

觀察 : 把 hash table 變大的時候 ,

需要把小 hash table 的東西通通倒出來 ,

算出每一個 pair 在大 hash table 的位置

然後重新放進大 hash table

有個可憐鬼做 insert 正好碰到應該 hash table rebuild 的時候 , 他就會等非常非常久 . T_T

(28)

Dynamic hashing

目標 : 重建的時候 , 不要一次把所以重建的事情都做完

或許 , 留一些之後慢慢做 ?

每個 operation 的時間都要合理

又叫做 extendible hashing

(29)

例子

k h(k)

A0 100 000

A1 100 001

B0 101 000

B1 101 001

C1 110 001

C2 110 010

C3 110 011

C5 110 101

h(k,i)=bits 0-i of h(k) Example:

h(A0,1)=0

h(A1,3)=001=1 h(B1,4)=1001=9

(30)

Dynamic hashing using directories

A0, B0 A1, B1 C2

C3 00

01 10

11 k h(k)

A0 100 000

A1 100 001

B0 101 000

B1 101 001

C1 110 001

C2 110 010

C3 110 011

C5 110 101

Insert C5 directory depth=

number of bits of the index of the hash table

h(C5, 2)=01=1

C5, overflow

A0, B0 A1, B1 C2

C3 000

001 010 011 100 101 110 111

C5

we increase d by 1

until not all h(k,d) of the keys in the cell are the same

動腦時間 :

如果原本的要加入 C1 呢 ?

如果第二步驟後加入 A4 呢 ? 答案 : p. 412-413

(31)

Dynamic hashing using directories

為什麼比較快 ?

只需要處理 overflow 的櫃子

如果把 directory 放在記憶體 , 而櫃子資料放在硬碟

search 只需要讀一次硬碟

insert 最多需要讀一次硬碟 ( 讀資料 , 發現 overflow 了 ), 寫兩次硬碟 ( 寫兩個新的櫃子 )

當要把 hash table 變兩倍大時 , 不需要碰硬碟 ( 只有改 d irectory)

(32)

Directoryless Dynamic hashing

假設 hash table 很大 , 但是我們不想一開始就整個開來 用 (initialization 會花很大 )

用兩個變數來控制的 hash table 大小 : r, q

hash table 開啟的地方為 0, 之間

•  

r=2, q=2

0~q-1 及之間使用 h(k,r+1)  

q~ 之間使用 h(k,r)  

(33)

Directoryless Dynamic hashing

每次輸入的時候 , 如果現在這個櫃子滿了

則開一個新的櫃子 :

原本 q 櫃子裡面的東西用

h(k,r+1) 分到 q 和兩櫃子裡

注意有可能還是沒有解決問題

多出來的暫時用 chain 掛在櫃子下面

•  

k h(k)

A0 100 000

A1 100 001

B4 101 100

B5 101 101

C1 110 001

C2 110 010

C3 110 011

C5 110 101

B4, A0 A1, B5 C2

C3 00

01 10 11

r=2, q=0

insert C5, full

A0

A1, B5 C2

C3 B4 000

01 10 11

r=2, q=1 C 5

100

問 : 再加入 C1 呢 ? ( 課本 p 415)

參考文獻

相關文件

K: 結果真的出現在 input 的各種

概念:  Hash  Table.

Grant, ed., The Process of Japanese Foreign Policy (London: Royal Institute of International Affairs, 1997), p.119.

討論結束,整理腦圖。首先嘗試將資料歸類,然 後可以開始收窄範圍,定出文章中心,再按照重

• vertex

之後每次從 heap 取 出一個 item, 放入 sorted list.. array of items 想是

left

 試著將投影片第 12 頁的範例加上 critical section ,解決 race