Algorithm Theory
ํด์ํ ์ด๋ธ(Hash Table)
Meng's Computer
2020. 12. 13. 00:14
๐ข ํด์ํ ์ด๋ธ(Hash Table)
-
(ํค-์ฃผ์) ๋งคํ์ ์ํด ๊ตฌํ๋ ์ฌ์ ADT
๐ ์ : ์ปดํ์ผ๋ฌ์ ์ฌ๋ณผ ํ ์ด๋ธ, ํ๊ฒฝ๋ณ์๋ค์ ๋ ์ง์คํ ๋ฆฌ - ํด์ํ
์ด๋ธ = ๋ฒ์ผ ๋ฐฐ์ด + ํด์ํจ์
๐ ํญ๋ชฉ๋ค์ ํค๋ฅผ ์ฃผ์(์ฆ, ๋ฐฐ์ด์ฒจ์)๋ก ๋งคํํจ์ผ๋ก์ 1์ฐจ์ ๋ฐฐ์ด์ ์ฌ์ ํญ๋ชฉ๋ค์ ์ ์ฅํ๋ค. - ์ฑ๋ฅ
๐ ํ์,์ฝ์ ,์ญ์ : ์ต์ ์ ๊ฒฝ์ฐ O(N), ๊ทธ๋ฌ๋ ๊ธฐ๋์๊ฐ O(1)
๐ข ๋ฒ์ผ๋ฐฐ์ด(Bucket Array)
-
ํค๊ฐ ์ ์ผํ ์ ์๋ฉฐ [0...M-1] ๋ฒ์์ ์ ๋ถํฌ๋์ด ์๋ค๋ฉด, ํด์ํ ์ด๋ธ์์์ ํ์, ์ฝ์ , ์ญ์ ์ O(1) ์์
- ๋ ๊ฐ์ง ์ค์ํ ๊ฒฐํจ
๐ O(N) ๊ณต๊ฐ์ ์ฌ์ฉํ๋ฏ๋ก, M์ด N์ ๋นํด ๋งค์ฐ ํฌ๋ฉด, ๊ณต๊ฐ ๋ญ๋น
๐ ํค๋ค์ด [0...M-1] ๋ฒ์ ๋ด์ ์ ์ผํ ์ ์์ฌ์ผ ํ์ง๋ง, ์ด๋ ์ข ์ข ๋นํ์ค์ - ์ค๊ณ ๋ชฉํ
๐ ๊ทธ๋ฌ๋ฏ๋ก ํด์ํ ์ด๋ธ ๋ฐ์ดํฐ๊ตฌ์กฐ๋ฅผ ์ ์ํ ๋๋, ํค๋ฅผ [0...M-1] ๋ฒ์ ๋ด์ ์ ์๋ก ๋งคํํ๋ ์ข์ ๋ฐฉ์๊ณผ
๋ฒ์ผ๋ฐฐ์ด์ ๊ตฌ์ฑํด์ผ ํ๋ค.
๐ข ํด์ํจ์ ๋ฐ ํด์ํ ์ด๋ธ
- ํด์ํจ์(Hash Function), h : ์ฃผ์ด์ง ํ์ ํค๋ฅผ ๊ณ ์ ๋ฒ์ [0...M-1]๋ก ๋งคํ
๐ ์ : h(x) = x % M ( h๋ ์ ์ ํค x์ ๋ํ ํด์ํจ์ ) - ์ ์ h(x) : ํค x์ ํด์๊ฐ(Hash value)
- ์ฃผ์ด์ง ํค ํ์ ํด์ํ
์ด๋ธ์ ๋ค์ ๋ ๊ฐ์ง๋ก ๊ตฌ์ฑ
๐ ํด์ํจ์ h
๐ ํฌ๊ธฐ M์ ๋ฐฐ์ด(ํ ์ด๋ธ์ด๋ผ ๋ถ๋ฅธ๋ค.) - ์ฌ์ ์ ํด์ํ ์ด๋ธ๋ก ๊ตฌํํ ๋, ๋ชฉํ๋ ํญ๋ชฉ(k,e)๋ฅผ ์ฒจ์ i = h(k)์ ์ ์ฅํ๋ ๊ฒ
- ํด์ํจ์(Hash Function)๋ ๋ณดํต ๋ ํจ์์ ๋ณตํฉ์ฒด๋ก ๋ช
์ธํ๋ค.
๐ ํด์์ฝ๋๋งต(Hash code map) h1 : keys -> integers
๐ ์์ถ๋งต(Compression map) h2 : integers -> [0...M-1] - ๋จผ์ ํด์์ฝ๋๋งต์ ์ ์ฉํ๊ณ , ๊ทธ ๊ฒฐ๊ณผ์ ์์ถ๋งต์ ์ ์ฉํ๋ค. ์ฆ,
๐ h(k) = h2(h1(k)) - ์ข์ ํด์ํจ์๊ฐ ๋๊ธฐ ์ํ ์กฐ๊ฑด
๐ ํค๋ค์ ์ธ๊ฒฌ์ ๋ฌด์์ํ๊ฒ(Random) ๋ถ์ฐ์์ผ์ผ ํ๋ค.
๐ ๊ณ์ฐ์ด ๋น ๋ฅด๊ณ ์ฌ์์ผ ํ๋ค ( ๊ฐ๋ฅํ๋ฉด ์์์๊ฐ )
๐ข ์์ถ๋งต
- ๋๋๊ธฐ(Division) (๋ณดํต์ฌ์ฉ ๋ฐฉ์)
๐ h2(k) = |k| % M
๐ ํด์ํ ์ด๋ธ์ ํฌ๊ธฐ M์ ์ผ๋ฐ์ ์ผ๋ก ์์(Prime)๋ก ์ ํ - ์นํฉ์ (MAD, Multiply Add and Divide)
๐ h2(k) = |ak + b| % M
๐ a์ b๋ ์์ด ์๋ ์ ์๋ก์, a % M != 0, ๊ทธ๋ ์ง ์์ผ๋ฉด, ๋ชจ๋ ์ ์๊ฐ ๋์ผํ ๊ฐ b๋ก ๋งคํ๋จ
๐ข ํด์์ฝ๋๋งต
- ๋ฉ๋ชจ๋ฆฌ ์ฃผ์(Memory address)
๐ ํค ๊ฐ์ฒด์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ์ ์๋ก ์ฌํด์( ๋ชจ๋ Java๊ฐ์ฒด๋ค์ ๊ธฐ๋ณธ ํด์์ฝ๋๋ค. )
๐ ์ผ๋ฐ์ ์ผ๋ก ๋ง์กฑ์ค๋ฌ์ฐ๋ ์์น ๋๋ ๋ฌธ์์ด ํค์๋ ์ ์ฉ ๊ณค๋ - ์ ์ ์บ์คํธ(Integer case)
๐ ํค์ ๋นํธ๊ฐ์ ์ ์๋ก ์ฌํด์
๐ ์ ์ํ์ ํ ๋น๋ ๋นํธ ์๋ฅผ ์ด๊ณผํ์ง ์๋ ๊ธธ์ด์ ํค์๋ ์ ๋น ( Java์ byte, short, int, float ) - ์์ํฉ(Component sum)
๐ ํค์ ๋นํธ๋ค์ ๊ณ ์ ๊ธธ์ด(16 or 32bit)์ ์์๋ค๋ก ๋ถํ ํ ํ ๊ฐ ใ ํฉํ๋ค(overflow๋ ๋ฌด์ํ๋ค.)
๐ ์ ์ํ์ ํ ๋น๋ ๋นํธ ์ ์ด์์ ๊ณ ์ ๊ธธ์ด์ ์์น ํค์ ์ ๋น ( ์ : Java์ long, double )
๐ ๋ฌธ์์ ์์์ ์๋ฏธ๊ฐ ์๋ ๋ฌธ์์ด ํค์๋ ๋ถ์ ๋น ( ์: temp01-temp10, stop-tops-spot-pots ) - ๋คํญ ๋์ (Ploynomial accumulation)
๐ ์์ํฉ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก, ํค์ ๋นํธ๋ค์ ๊ณ ์ ๊ธธ์ด(8,16,32bit)์ ์์๋ค๋ก ๋ถํ ( a(0),a(1),...,a(N-1) )
๐ ๊ณ ์ ๊ฐ z๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ ์์์ ์์น์ ๋ฐ๋ฅธ ๋ณ๋ ๊ณ์ฐ์ ๋ถ๊ณผํ ๋คํญ์ p(z)๋ฅผ ๊ณ์ฐ (overflow ๋ฌด์)
๐ p(z) = a(0) + a(1) * z + a(2) * z^2 + .... + a(N-1) * z ^ (N-1)
๐ ๋ฌธ์์ด์ ํนํ ์ ๋น ( ์ : ๊ณ ์ ๊ฐ z = 33์ ์ ํํ ๊ฒฝ์ฐ, 50,000๊ฐ์ ์๋จ์ด์ ๋ํด ๋จ์ง 6ํ ์ถฉ๋๋ง ๋ฐ์
๐ข ์ถฉ๋ํด์ (์ค์ !!)
- ์ถฉ๋(Collision) : ๋ ๊ฐ ์ด์์ ์์๋ค์ด ๋์ผํ ์ ๋ก ๋งคํ๋๋ ๊ฒ
- ์ฆ, ์์ดํ ํค, k1๊ณผ k2์ ๋ํด h(k1) = h(k2)๋ฉด "์ถฉ๋์ด ์ผ์ด๋ฌ๋ค."๊ณ ๋งํ๋ค.
- ์ถฉ๋ ํด๊ฒฐ(Collision resolution)์ ์ํ ์ผ๊ด๋ ์ ๋ต์ด ํ์ํ๋ค.
๐ ๋ถ๋ฆฌ์ฐ์๋ฒ(Separate Chaining)
๐ ์ ํ์กฐ์ฌ๋ฒ(Linear Probing)
๐ 2์ฐจ ์กฐ์ฌ๋ฒ(Quadratic Probing)
๐ ์ด์คํด์ฑ(Double Hashing)
๐ข ๋ถ๋ฆฌ์ฐ์๋ฒ
- ๋ถ๋ฆฌ์ฐ์๋ฒ(Separate Chaining), ์ฐ์๋ฒ : ๊ฐ ๋ฒ์ผ A[i]๋ ๋ฆฌ์คํธ L(i)์ ๋ํ ์ฐธ์กฐ๋ฅผ ์ ์ฅ ( L(i)๋ ๋ฆฌ์คํธ )
๐ ํด์ํจ์๊ฐ ๋ฒ์ผ A[i]๋ก ๋งคํํ ๋ชจ๋ ํญ๋ชฉ๋ค์ ์ ์ฅ
๐ ๋ฌด์๋ฆฌ์คํธ๊ฐ ๋๋ ๊ธฐ๋กํ์ผ ๋ฐฉ์์ ์ฌ์ฉํ์ฌ ๊ตฌํ๋ ๋ฏธ๋ ์ฌ์ ์ด๋ผ ๋ณผ ์ ์๋ค. - ์ฅ๋จ์ : ๋จ์ํ๊ณ ๋น ๋ฅด๋ค๋ ์ฅ์ ์ด ์์ผ๋ ํ ์ด๋ธ ์ธ๋ถ์ ์ถ๊ฐ์ ์ธ ์ ์ฅ๊ณต๊ฐ์ ์๊ตฌ
- ์์
๐ h(k) = k % M
๐ ํค : 25,13,16,15,7,28,31,20,1 ( = ์ถฉ๋ ์ผ์ด๋ ํค๊ฐ )
๐ ๋ฆฌ์ค์ ์ถ๊ฐ๋๋ ํญ๋ชฉ๋ค์ ์์น๋, ๋ฆฌ์คํธ์ ๋งจ ์์ ์ฝ์ ํ๋ ๊ฒ์ด ์ ๋ฆฌํ๋ค. (๋ฆฌ์คํธ์ tail ํฌ์ธํฐ ์๋๊ฒฝ์ฐ)
๐ข ๊ฐ๋ฐฉ์ฃผ์๋ฒ ( ์ ํ์กฐ์ฌ๋ฒ )
- ๊ฐ๋ฐฉ์ฃผ์๋ฒ(Open Addresssing) : ์ถฉ๋ ํญ๋ชฉ์ ํ ์ด๋ธ์ ๋ค๋ฅธ ์ ์ ์ ์ฅ
- ์ฅ๋จ์ : ๋ถ๋ฆฌ์ฐ์๋ฒ์ ๋นํด ๊ณต๊ฐ ์ฌ์ฉ์ ์ ์ฝํ์ง๋ง, ์ญ์ ๊ฐ ์ด๋ ต๋ค๋ ๊ฒ๊ณผ ์ฌ์ ํญ๋ชฉ๋ค์ด ์ฐ์ด์ด ๊ตฐ์งํ
- ์ ํ์กฐ์ฌ๋ฒ(Linear Probing) : ์ถฉ๋ ํญ๋ชฉ์ (์ํ์ผ๋ก)๋ฐ๋ก ๋ค์์ ๋น์ด์๋ ํ ์ด๋ธ ์ ์ ์ ์ฅํจ์ผ๋ก์จ ์ถฉ๋์ ์ฒ๋ฆฌ
- ์ฆ, ๋ค์ ์์์ ์ํด ๋ฒ์ผ์ ์กฐ์ฌํ๋ค.
๐ A[ (h(k) + f(i)) % M ], f(i) = i, i = 0,1,2,... - ๊ฒ์ฌ๋๋ ๊ฐ ํ ์ด๋ธ ์ ์ ์กฐ์ฌ(Probe)๋ผ ๋ถ๋ฆฐ๋ค.
- ์ถฉ๋ ํญ๋ชฉ๋ค์ ๊ตฐ์งํํ๋ฉฐ, ์ดํ์ ์ถฉ๋์ ์ํด ๋์ฑ ๊ธด ์กฐ์ฌ์ด(Probe sequence)๋ก ๊ตฐ์ง๋จ = "1์ฐจ ๊ตฐ์งํ"
- ์์
๐ h(k) = k % M
๐ ํค : 25,13,16,15,7,28,31,20,1,38 ( = ์ถฉ๋ ํค )
๐ข ๊ฐ๋ฐฉ ์ฃผ์๋ฒ( 2์ฐจ ์กฐ์ฌ๋ฒ )
- 2์ฐจ ์กฐ์ฌ๋ฒ(Quadratic Probing) : ๋ค์ ์์์ ์ํด ๋ฒ์ผ์ ์กฐ์ฌ
๐ A[ (h(k) + f(i) % M ], f(i) = i^2, i = 0,1,2,... - ํด์ ๊ฐ์ด ๋์ผํ ํค๋ค์ ๋์ผํ ์กฐ์ฌ๋ฅผ ์๋ฐํ๋ค.
- 1์ฐจ ๊ตฐ์งํ๋ฅผ ํผํ์ง๋ง, ๋๋ฆ๋๋ก์ ๊ตฐ์ง์ ํ์ฑ ํ ์ ์๋ค. = "2์ฐจ ๊ตฐ์งํ"
- M์ด ์์๊ฐ ์๋๊ฑฐ๋ ๋ฒ์ผ ๋ฐฐ์ด์ด ๋ฐ ์ด์ ์ฐจ๋ฉด, ๋น์ด ์๋ ๋ฒ์ผ์ด ๋จ์ ์๋๋ผ๋ ์ฐพ์ง ๋ชปํ ์ ์๋ค. ( ๋จ์ )
- ์์
๐ h(k) = k % M, f(i) = i^2
๐ ํค : 25,13,16,15,7,28,31,20,1,38
๐ข ์ด์คํด์ฑ
- ์ด์คํด์ฑ(Double Hashing) : ๋ ๋ฒ์งธ์ ํด์ํจ์ h`๋ฅผ ์ฌ์ฉํ์ฌ ๋ค์ ์์์ ์ํด ๋ฒ์ผ์ ์กฐ์ฌ
๐ A[ (h(k) + f(i)) % M ], f(i) = i * h`(k), i = 0,1,2,.... - ๋์ผํ ํด์๊ฐ์ ๊ฐ์ง๋ ํค๋ค๋ ์์ดํ ์กฐ์ฌ๋ฅผ ์๋ฐํ ์ ์๊ธฐ ๋๋ฌธ์ ๊ตฐ์งํ๋ฅผ ์ต์ํํ๋ค.
- h`๋ ๊ณ์ฐ ๊ฒฐ๊ณผ๊ฐ 0์ด ๋๋ฉด ์๋๋ค. ๐ ( 0์ด ๋๋ฉด, f(i)๋ ๊ฒฐ๊ณผ์ ์ผ๋ก 0๋ง ๋๊ฒ ์ฃ ? ๊ทธ๋ผ ํ์๋ง ๊ณ์ ํด์ฑ์ถฉ๋ )
- ์ต์ ์ ๊ฒฐ๊ณผ๋ฅผ ์ํด, h`(k)์ M์ ์๋ก์(Relative Prime)์ฌ์ผ ํ๋ค.
๐ d(1)*M = d(2)*h`(k)์ด๋ฉด, d(2) ๊ฐ์ ์กฐ์ฌ๋ง ์๋ํ๋ค. ์ฆ, ๋ฒ์ผ๋ค ์ค d(2)/M๋ง ๊ฒ์ฌ
๐ h`(k) = q - (k % q) ๋๋ 1 + (k % q)๋ฅผ ์ฌ์ฉ ( ๋จ, q < M์ ์์๋ฉฐ M ์ญ์ ์์์ผ ๊ฒฝ์ฐ )
๐ ํ ๋ง๋๋ก ์์ ๋ ์กฐ๊ฑด์ ๋ง์กฑ์ํค๋, ํด์ํจ์๋ฅผ ์ ์ฉํ๋ฉด, ๊ตฐ์งํ๋ฅผ ์ต์ํํ๋ฉด์, ์ต์ํ๋ก ์คํ๊ฐ๋ฅ - ์์
๐ h(k) = k % M, h`(k) = 11 - (k % 11), ( ์ด๋ q = 11์ด๊ณ , 11์ ์๋ก์์ด๋ค. )
๐ ํค : 25,13,16,15,7,28,31,20,1,38 ( = ์ถฉ๋ ํค )
- ๊ฐ๋ฐฉ์ฃผ์๋ฒ( ์ ํ์กฐ์ฌ๋ฒ, 2์ฐจ์กฐ์ฌ๋ฒ ), ์ด์คํด์ฑ ์๊ณ ๋ฆฌ์ฆ
Alg findElement(k)
input bucket array A[0...M-1], hash function h, key k
output element with key k
v <- h(k) // h(k) = ํด์ํจ์๋ ๋ณดํต ์ฃผ์ด์ง๋ค.
i <- 0
while(i < M)
b <- getNextBucket(v,i)
if(isEmpty(A[b])
return NoSuchKey
elseif(k == key(A[b])
return element(A[b])
else
i <- i + 1
return NoSuchKey
=========================================================
Alg insertItem(k,e)
v <- h(k)
i <- 0
while(i < M)
b <- getNextBucket(v,i)
if(isEmpty(A[b]))
Set bucket A[b] to (k,e)
return
else
i <- i + 1
overflowException()
return
Alg getNextBucket(v,i) // ์ ํ์กฐ์ฌ๋ฒ
return (v + i) % M
==========================================
Alg getNextBucket(v,i) // 2์ฐจ์กฐ์ฌ๋ฒ
return (v + i^2) % M
==========================================
Alg getNextBucket(v,i) // ์ด์คํด์ฑ
return (v + i * h`(k)) % M
===========================================
Alg initBucketArray() // ๋ฒํท์ด๊ธฐํ(์์)
input bucket array A[0...M-1]
output bucket array A[0...M-1] initialized with null buckets
for i <- 0 to M-1
A[i].empty <- 1 // Set empty
return
===========================================
Alg isEmpty(b)
input bucket b
output boolean
return b.empty
๐ข ์ ์ฌ์จ
- ํด์ํ
์ด๋ธ์ ์ ์ฌ์จ(Load factor), a = N/M ( N์ ํค ์, M์ ๋ฒ์ผ๋ฐฐ์ด ํฌ๊ธฐ )
๐ ์ฆ, ์ข์ ํด์ํจ์๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ์ ๊ฐ ๋ฒ์ผ์ ๊ธฐ๋ํฌ๊ธฐ - ์ ์ฌ์จ์ ๋ฎ๊ฒ ์ ์ง๋์ด์ผ ํ๋ค ( ๊ฐ๋ฅํ๋ฉด 1 ์๋๋ก, ์ฆ a = N/M < 1 ๋๋๋ก)
- ์ข์ ํด์ํจ์๊ฐ ์ฃผ์ด์ก๋ค๋ฉด, ํ์,์ฝ์ ,์ญ์ ๊ฐ ์์ ์ ๊ธฐ๋ ์คํ์๊ฐ = O(a)
- ๋ถ๋ฆฌ์ฐ์๋ฒ
๐ a > 1 ์ด๋ฉด, ์๋์ ํ์ง๋ง ๋นํจ์ธ์
๐ a < 1 ์ด๋ฉด, O(a) = O(1)์ ๊ธฐ๋์คํ์๊ฐ ์ฑ์ทจ ๊ฐ๋ฅ - ๊ฐ๋ฐฉ์ฃผ์๋ฒ ( ์ ํ์กฐ์ฌ๋ฒ, 2์ฐจ์กฐ์ฌ๋ฒ )
๐ ํญ์ a < 1
๐ a > 0.5 ์ด๋ฉด, ์ ํ ๋ฐ 2์ฐจ ์กฐ์ฌ์ธ ๊ฒฝ์ฐ ๊ตฐ์งํ ๊ฐ๋ฅ์ฑ ๋ํํ๋ค.
๐ a <= 0.5 ์ด๋ฉด, O(a) = O(1) ๊ธฐ๋์คํ์๊ฐ
๐ข ํด์ฑ์ ์ฑ๋ฅ
- ํด์ํ
์ด๋ธ์ ๋ํ ํ์,์ฝ์
,์ญ์
๐ (์ต์ ์ ๊ฒฝ์ฐ) O(N) ์๊ฐ ์์ - ์ต์ ์ ๊ฒฝ์ฐ๋ : ์ฌ์ ์ ์ฝ์ ๋ ๋ชจ๋ ํค๊ฐ ์ถฉ๋ํ ๊ฒฝ์ฐ
- ์ ์ฌ์จ(Load factor) : a = N/M์ ํด์ํ ์ด๋ธ์ ์ฑ๋ฅ์ ์ข์ฐํ๋ค.
- ํด์๊ฐ๋ค์ ํํ, ๋์(Random numbers)์ ๊ฐ๋ค๊ณ ๊ฐ์ ํ๋ฉด, ๊ฐ๋ฐฉ์ฃผ์๋ฒ(์ ํ์กฐ์ฌ๋ฒ or 2์ฐจ์กฐ์ฌ๋ฒ)์ ์ํ
์ฝ์ ์ ์ํ ๊ธฐ๋ ์กฐ์ฌํ์๋ 1/(1 - a)๋ผ๊ณ ์๋ ค์ ธ ์๋ค. - ํด์ํ ์ด๋ธ์์ ๋ชจ๋ ์ฌ์ ADT ์์ ๋ค์ ๊ธฐ๋์คํ์๊ฐ : O(1)
- ์ค์ ์์, ์ ์ฌ์จ์ด 1(์ฆ, 100%)์ ๊ฐ๊น์ง๋ง ์๋ค๋ฉด, ํด์ฑ์ ๋งค์ฐ ๋น ๋ฅธ ๊ฒ์ด๋ค.
- ์์ฉ๋ถ์ผ
๐ ์๊ท๋ชจ ๋ฐ์ดํ ๋ฒ ์ด์ค ( ์ธ๋ฑ์ค )
๐ ์ปดํ์ผ๋ฌ
๐ ๋ธ๋ผ์ฐ์ ์บ์
728x90
๋ฐ์ํ