Hash Table μ΄λ
Hash Tableμ λ°μ΄ν°λ₯Ό key-value νμμΌλ‘ 보κ΄νμ¬ κ²μ · μ½μ · μμ λ₯Ό O(1) μκ° λ³΅μ‘λλ‘ μνν μ μλ μλ£κ΅¬μ‘°μ΄λ€.
Hash Tableμ key κ°μ ν΅ν΄ λ°μ΄ν°λ₯Ό λ€λ£¨κΈ° λλ¬Έμ, key κ°μ κ³ μ ν΄μΌνλ€.
μ΄λ¬ν κ³ μ ν key κ°μ λ§λλ μμ μ ν΄μ ν¨μκ° λ΄λΉνλλ°,
λνμ μΌλ‘λ key κ°μ ASCII κ°μ ν©νμ¬ λ§λλ κ°λ¨ν λ°©λ²μ΄ μλ€.
μ΄λ¬ν ν΄μ ν¨μκ° keyλ₯Ό λ§λλ κ³Όμ μμ, μλνμ§ μκ² μ°μ°ν key κ°μ΄ μΌμΉνλ κ²½μ°κ° λ°μν μ μλλ°
π‘ μ΄λ₯Ό ν΄μ μΆ©λμ΄λΌκ³ νλ€.
ν΄μ μΆ©λμ΄ λ°μνλ©΄, key κ°μ΄ μ€λ³΅λμ΄ λ°μ΄ν°κ° μ¬λΌμ§ μ μλ€. λ°λΌμ ν΄μ μΆ©λμ΄ λ°μνλ©΄ λμ²ν΄μΌνλ€.
λνμ μΈ λ°©λ²μΌλ‘λ
- 체μΈλ² (Seperate Chaning)
- μ€ν μ£Όμλ² (Open Addressing)
λκ°μ§ λ°©λ²μ΄ μλ€.
ν΄μ μΆ©λ λμ²λ²
체μΈλ²
체μΈλ²μ ν΄μ κ°μ΄ κ°μ λ°μ΄ν°λ₯Ό μ¬μ¬(chain) λͺ¨μμ μ°κ²° 리μ€νΈλ‘ μ°κ²°νλ λ°©λ²μ΄λ€.
μ κ·Έλ¦Όκ³Ό κ°μ΄ key κ°μ΄ 152
μΈ μμΉμ John Smith
λ°μ΄ν°κ° μ‘΄μ¬νλλ°
Sandra Dee
μμ key κ°μ΄ 152 λ‘ ν΄μ μΆ©λμ΄ λ°μνλ€.
μ΄λ° κ²½μ° key κ°μ ν΄λΉνλ κ° valueλ μ°κ²°λ¦¬μ€νΈλ‘ ꡬμ±ν΄λκ³ , valueκ° λ€μ΄μ¬λ λ§λ€ λ Έλλ₯Ό μΆκ°ν΄μ£Όλ λ°©μμΌλ‘ λμ²ν μ μλ€.
π¨ μ°Έκ³ λ‘ μ°κ²°λ¦¬μ€νΈλ₯Ό ν€ κ°μ ν΄μ±ν κ°μΌλ‘ μ°Ύμκ°κ³ , μ°κ²°λ¦¬μ€νΈλ₯Ό μννλ©΄μ ν΄μ±νκΈ° μ ν€ κ°κ³Ό μΌμΉνλ λ Έλκ° λμ¬λκΉμ§ νμνλ μμ μΌλ‘ μνλ λ Έλλ₯Ό μ°Ύμ μ μκ² λλ€.
Node μ μ
public class ChainHash<K, V> {
class Node<K, V> {
private K key;
private V value;
private Node<K, V> next;
public Node(K key, V value, Node<K, V> next) {
this.key = key;
this.value = value;
this.next = next;
}
K getKey() {
return key;
}
V getValue() {
return value;
}
public int hashCode() {
return key.hashCode();
}
}
κΈ°λ³Έ κ΅¬μ± νμ μμ κ°λ€.
ν€ κ°μΈ Kμ ν΄λΉνλ κ³³μ Node<K,V>
λ
Έλ ν΄λμ€κ° μ‘΄μ¬νλ€.
κ·Έλ¦¬κ³ μ΄ λ Έλλ λ€μ λ Έλλ₯Ό μ°Έμ‘°ν μ μμΌλ―λ‘, ν΄μ μΆ©λμ΄ λ°μνμ λ next λ³μμ λ€λ₯Έ λ Έλλ₯Ό μ°κ²°μμΌμ£Όλ©΄ λλ€.
Hash table μ μ
public class ChainHash<K,V> {
private int size;
private Node<K, V>[] table;
public ChainHash(int size) {
try {
table = new Node[size];
this.size = size;
} catch (OutOfMemoryError e) {
this.size = 0;
}
}
public int hashValue(Object key) {
return key.hashCode() % size;
}
}
μ΄μ μ μ μν Nodeλ₯Ό νμ©νμ¬ ν μ΄λΈμ μμ±νλ€.
κ²μ
public V search(K key) {
// ν€ κ°μ ν΄λΉνλ ν΄μ κ°μΌλ‘ μ κ·Ό
int hash = hashValue(key);
Node<K, V> node = table[hash];
// ν΄μκ°μ ν΄λΉνλ μ°κ²°λ¦¬μ€νΈμ μΌμΉνλ ν€κ°μ κ°μ§ λ
Έλκ° λνλ λκΉμ§ νμ
while (node != null) {
if (node.getKey().equals(key)) {
return node.getValue();
}
node = node.next;
}
// κ²μ μ€ν¨
return null;
}
μ΄μ μ μ€λͺ νλ―, ν€ κ°μ ν΄μ±ν κ°μΌλ‘ μ°κ²°λ¦¬μ€νΈμ μ κ·Όνλ€.
μ°κ²°λ¦¬μ€νΈμ μ κ·Όν΄μλ, ν΄μ±νκΈ° μ ν€ κ°κ³Ό μΌμΉνλ ν€λ₯Ό κ°μ§ λ Έλλ₯Ό λ°κ²¬ν λκΉμ§ μννλ€.
μΆκ°
public int add(K key, V value) {
int hash = hashValue(key);
// ν΄μκ°μ ν΄λΉνλ μ°κ²°λ¦¬μ€νΈ μ κ·Ό
Node<K, V> node = table[hash];
// λΉ λ
Έλλ‘ μ κ·Ό
while (node != null) {
// λ§μ½ μ
λ ₯νλ €λ ν€ κ°μ ν΄λΉνλ λ
Έλκ° μ΄λ―Έ μ‘΄μ¬νλ€λ©΄
if (node.getKey().equals(key)) {
return 1;
}
node = node.next;
}
// λ
Έλ μμ± ν μ
λ ₯
Node<K, V> temp = new Node<K, V>(key, value, table[hash]);
table[hash] = temp;
return 0;
}
μΆκ° μμ, κ²μκ³Ό μ μ¬νκ², ν΄μ κ°μ ν΄λΉνλ λ Έλλ‘ μ κ·Όν΄μ λΉ λ Έλκ° λμ¬λκΉμ§ μ΄λν λ€
λ Έλλ₯Ό μΆκ°νλ λ°©μμΌλ‘ ꡬννλ©΄ λλ€.
μ€ν μ£Όμλ²
체μ΄λ λ°©μμ λ Έλλ₯Ό κ³μ μΆκ°ν΄μ£Όλ€λ³΄λ©΄ μΆκ°μ μΈ λ©λͺ¨λ¦¬λ₯Ό μ¬μ©νκ² λλ€.
μ€ν μ£Όμλ²μ μΆκ° 곡κ°μ μ¬μ©νμ§ μκ³ ν΄κ²°νλ λ°©λ²μ΄λ€.
π‘ μΆ©λμ΄ μΌμ΄λ¬μ λ, μ ν΄μ§ κ·μΉμ λ°λΌ λ€λ₯Έ μ리λ₯Ό μ°Ύμ μ μ₯νλ λ°©μμΌλ‘ ν΄μ μΆ©λμ λμ²νλ€.
λνμ μΌλ‘λ μΆ©λμ΄ λ°μνμ λ μ¬ν΄μλ₯Ό μννμ¬ λΉμ΄μλ λ²ν·μ μ°Ύμλ΄λ λ°©λ²μ΄ μλ€.
Bucket μ μ
public class OpenHash<K, V> {
enum Status {OCCUPIED, EMPTY, DELETED}
static class Bucket<K, V> {
private K key;
private V value;
private Status status;
public Bucket() {
this.status = Status.EMPTY;
}
void set(K key, V value, Status status) {
this.key = key;
this.value = value;
this.status = status;
}
void setStatus(Status status) {
this.status = status;
}
K getKey() {
return this.key;
}
V getValue() {
return this.value;
}
public int hashCode() {
return this.key.hashCode();
}
}
}
ν΄μ ν μ΄λΈμ ν΄μλ‘ μ κ·Όνλ©΄ μμ κ°μ λ²ν·μ΄ μ‘΄μ¬νκ³
κ° λ²ν·μ μνλ₯Ό λνλ΄λ status
νλλ₯Ό κ°λλ€.
μ΄ status
νλλ₯Ό κ°λ μ΄μ λ, νμ μ μ¬ ν΄μ νλ©΄μ λ²ν·μ ν€μ μΌμΉνλμ§ νμΈν΄μΌνλλ°
3λ² μ¬ν΄μ λ λ°μ΄ν°λ₯Ό μ°Ύλ κ²½μ°, 2λ²μ§Έ μ¬ν΄μλ λ°μ΄ν°κ° μμ λλ©΄ λ°μ΄ν°λ₯Ό μ°Ύμ§ λͺ»νλ κ²½μ°κ° λ°μν μ μκΈ° λλ¬Έμ
λ°μ΄ν° μμ μ, DELETE
νμλ‘ μμ λ¨μ λνλ΄μ£ΌκΈ° μν¨μ΄λ€.
Hash Table μ μ
public class OpenHash<K, V> {
private int size;
private Bucket<K, V>[] table;
public OpenHash(int size) {
try {
table = new Bucket[size];
for (int i = 0; i < size; i++) {
table[i] = new Bucket<>();
}
this.size = size;
} catch (OutOfMemoryError e) {
this.size = 0;
}
}
public int hashValue(Object key) {
return key.hashCode() % size;
}
public int rehashValue(int hash) {
return (hash + 1) % size;
}
}
μ΄μ μ μ μν Bucket
μ κ°λ λ°°μ΄μ μμ±ν΄μ€λ€.
κ·Έλ¦¬κ³ , ν΄μ μΆ©λ λ°μ μ λ€λ₯Έ ν΄μ κ°μ λ°ννλλ‘ νλ rehashValue
λ©μλλ μ μν΄μ€λ€.
κ²μ
public V search(K key) {
Bucket<K, V> bucket = searchNode(key);
return bucket == null ? null : bucket.getValue();
}
private Bucket searchNode(K key) {
int hash = hashValue(key);
Bucket<K, V> bucket = table[hash];
// λ²μΌμ΄ EMPTY κ° μλλκΉμ§ κ²μ, DELETE λ λ²ν·μ΄μ΄λ κ²μ μ§ν λ¨
for (int i = 0; bucket.status != Status.EMPTY && i < size; i++) {
if (bucket.status == Status.OCCUPIED && bucket.getKey().equals(key)) {
return bucket
}
hash = rehashValue(hash);
bucket = table[hash];
}
return null;
}
κ²μ μ, λ²μΌμ μνκ° EMPTY
κ° μλλΌλ©΄ μ¬ν΄μλ₯Ό λ°λ³΅ν΄μ μνλ ν€κ°μ κ°μ§ λ²μΌμ΄ λ°κ²¬λ λκΉμ§ μ§ννλ€.
μΆκ°
public int add(K key, V value) {
// μ΄λ―Έ μ‘΄μ¬νλ κ²½μ°
if (search(key) != null) {
return 1;
}
int hash = hashValue(key);
Bucket<K, V> bucket = table[hash];
for (int i = 0; i < size; i++) {
// ν΄λΉ λ²μΌμ΄ λΉμ΄μκ±°λ DELETED λ μνμΈ κ²½μ° λ°μ΄ν° μΆκ°
if (bucket.status == Status.EMPTY || bucket.status == Status.DELETED) {
bucket.set(key, value, Status.OCCUPIED);
return 0;
}
hash = rehashValue(hash);
bucket = table[hash];
}
// ν
μ΄λΈμ΄ κ°λ μ°¬ κ²½μ°
return 2;
}
μΆκ°νλ κ³Όμ μμ, μ¬ν΄μ κ³Όμ μ κ±°μΉλ©΄μ λΉμ΄μκ±°λ μμ λμ΄ μ¬μ©λμ§ μλ λ²μΌμ μ°Ύκ³
κ·Έ λ²μΌμ λ°μ΄ν°λ₯Ό μ§μ΄ λ£λ λ°©μμΌλ‘ λμνλ€.
체μΈλ²κ³Ό μ€ν μ£Όμλ²μ νΉμ§(μ₯λ¨μ )
π‘ κ·Έλ λ€λ©΄ κ° λ°©μμ νΉμ§μ λ€μ μ 리ν΄λ³΄μ.
- 체μΈλ²
- μ°κ²° 리μ€νΈλ₯Ό μ¬μ©νμ¬ ν΄μμ½λλ₯Ό λ€μ κ³μ°ν΄μΌνλ μ μ°¨κ° νμμλ€.
- νΉμ ν΄μ κ°μ μ°κ²° 리μ€νΈκ° λ§μ΄ μΆκ°λλ©΄ μ±λ₯μ΄ μ νλκ³ μΆκ°μ μΈ λ©λͺ¨λ¦¬λ₯Ό μ¬μ©νκ²λλ€.
- ν΄μ ν
μ΄λΈμ μ체μ ν¬κΈ°(λ
Έλ κ°μ λ§κ³ )λ₯Ό λμ μΌλ‘ μ‘°μ νκΈ° μ΄λ ΅λ€.
- μ€ν μ£Όμλ²
- μΆκ°μ μΈ λ©λͺ¨λ¦¬ 곡κ°μ΄ νμμλ€.
- μ΅μ μ κ²½μ° ν μ΄λΈ μ 체λ₯Ό κ²μν΄μΌν μ μκ³ ν μ΄λΈμ λ‘λ ν©ν°(ν μ΄λΈμ κ°λ μ°¬ μ λ)κ° κΈλ°© λλ¬νμ¬ λ¦¬μ¬μ΄μ§μ΄ νμν μ μλ€.
- λμ μΌλ‘ ν¬κΈ°λ₯Ό μ‘°μ νκΈ° μ½λ€.