1οΈβ£ ν΄μ ν μ΄λΈ(Hash Table).
ν΄μ ν μ΄λΈ(Hash Table)μ λ°μ΄ν°λ₯Ό ν€-κ° μ(key-value pairs)μΌλ‘ μ μ₯νλ μλ£κ΅¬μ‘°μ λλ€.
ν΄μ ν μ΄λΈμ ν΄μ ν¨μλ₯Ό μ¬μ©νμ¬ ν€λ₯Ό ν΄μ κ°μΌλ‘ λ³ννκ³ , μ΄ ν΄μ κ°μ μΈλ±μ€λ‘ μ¬μ©νμ¬ λ°°μ΄μμ κ°μ μ μ₯νκ±°λ κ²μν©λλ€.
μ΄λ₯Ό ν΅ν΄ λ°μ΄ν°μ λΉ λ₯΄κ² μ κ·Όν μ μμ΅λλ€.
1οΈβ£ ν΄μ ν μ΄λΈμ κ΅¬μ± μμ.
-
ν€(key) : κ° λ°μ΄ν°λ₯Ό μλ³νκΈ° μν κ³ μ ν μλ³μμ λλ€.
-
κ°(Value) : ν€μ μ°κ΄λ λ°μ΄ν°μ λλ€.
-
ν΄μ ν¨μ(Hash Function) : ν€λ₯Ό μ λ ₯μΌλ‘ λ°μ ν΄μ κ°μ μΆλ ₯νλ ν¨μμ λλ€. μ΄ ν΄μ κ°μ λ³΄ν΅ μ μμ΄λ©°, λ°°μ΄μ μΈλ±μ€λ‘ μ¬μ©λ©λλ€.
-
λ²ν·(Bucket) : ν΄μ κ°μ μν΄ μΈλ±μ±λλ λ°°μ΄μ κ° μμΉμ λλ€. κ° λ²ν·μ νλμ ν€-κ° μ λλ μΆ©λ μ²λ¦¬λ₯Ό μν λ°μ΄ν° ꡬ쑰(μ: μ°κ²° 리μ€νΈ)λ₯Ό μ μ₯ν μ μμ΅λλ€.
2οΈβ£ ν΄μ ν¨μμ μν .
ν΄μ ν¨μλ ν€λ₯Ό κ³ μ λ ν¬κΈ°μ ν΄μ κ°μΌλ‘ 맀νν©λλ€.
μ΄μμ μΈ ν΄μ ν¨μλ ν€λ₯Ό κ· λ±νκ² λΆν¬μν€κ³ , μΆ©λμ μ΅μνν©λλ€.
3οΈβ£ μΆ©λ(Collision)κ³Ό μΆ©λ ν΄κ²° λ°©λ².
λ κ° μ΄μμ ν€κ° λμΌν ν΄μ κ°μ κ°μ§ λ μΆ©λμ΄ λ°μν©λλ€.
ν΄μ ν μ΄λΈμ μ΄λ¬ν μΆ©λμ μ²λ¦¬νκΈ° μν μ¬λ¬κ°μ§ λ°©λ²μ μ 곡ν©λλ€.
-
체μ΄λ(Chaining) : κ° λ²ν·μ μ°κ²° 리μ€νΈλ₯Ό μ¬μ©νμ¬ λμΌν ν΄μ κ°μ κ°λ λͺ¨λ μμλ₯Ό μ μ₯ν©λλ€. μΆ©λμ΄ λ°μνλ©΄ ν΄λΉ λ²ν·μ 리μ€νΈμ μμλ₯Ό μΆκ°ν©λλ€.
-
κ°λ°© μ£Όμλ²(Open Addressing) : μΆ©λμ΄ λ°μνλ©΄ λ€λ₯Έ λΉ λ²ν·μ μ°Ύμ λ°μ΄ν°λ₯Ό μ μ₯ν©λλ€. μ΄λ₯Ό μν΄ λ€μν νμ¬ λ°©λ²(μ: μ ν νμ¬, μ κ³± νμ¬, μ΄μ€ ν΄μ±)μ μ¬μ©ν©λλ€.
4οΈβ£ ν΄μ ν μ΄λΈμ μκ° λ³΅μ‘λ.
- κ²μ(Search) : O(1)(νκ· ), O(n)(μ΅μ )
- μ½μ (Insertion) : O(1)(νκ· ), O(n)(μ΅μ )
- μμ (Deletion) : O(1)(νκ· ), O(n)(μ΅μ )
μ΅μ μ κ²½μ° μκ° λ³΅μ‘λλ ν΄μ μΆ©λλ‘ μΈν΄ λͺ¨λ μμκ° νλμ λ²ν·μ μ μ₯λ λ λ°μν©λλ€.
κ·Έλ¬λ, μ’μ ν΄μ ν¨μμ μΆ©λ ν΄κ²° λ°©λ²μ μ¬μ©νλ©΄ νκ· μ μΌλ‘ O(1)μ μ±λ₯μ μ μ§ν μ μμ΅λλ€.
5οΈβ£ ν΄μ ν μ΄λΈμ μ₯μ κ³Ό λ¨μ .
μ₯μ
- λΉ λ₯Έ κ²μ, μ½μ , μμ μ±λ₯(νκ· μ μΌλ‘ O(1))
- ν€λ₯Ό μ¬μ©νμ¬ λ°μ΄ν°μ λΉ λ₯΄κ² μ κ·Ό κ°λ₯
λ¨μ
- ν΄μ ν¨μμ μ±λ₯μ μμ‘΄
- μΆ©λ μ²μ΄ νμ
- λ©λͺ¨λ¦¬ μ¬μ©λμ΄ μ¦κ°ν μ μμ΄(νΉν 체μ΄λμ μ¬μ©νλ κ²½μ°)
π» ν΄μ ν μ΄λΈμ ꡬν μμ .
μλλ Javaμμ κ°λ¨ν ν΄μ ν μ΄λΈμ ꡬνν μμ μ λλ€.
// HashTable
import java.util.LinkedList;
class HashTable {
private class HashNode {
String key;
String value;
HashNode next;
public HashNode(String key, String value) {
this.key = key;
this.value = value;
}
}
private LinkedList<HashNode>[] buckets;
private int numBuckets;
private int size;
public HashTable() {
numBuckets = 10; // λ²ν·μ μ΄κΈ° ν¬κΈ°
buckets = new LinkedList[numBuckets];
size = 0;
for (int i = 0; i < numBuckets; i++) {
buckets[i] = new LinkedList<>();
}
}
private int getBucketIndex(String key) {
int hashCode = key.hashCode();
int index = hashCode % numBuckets;
return index < 0 ? index * -1 : index;
}
public void put(String key, String value) {
int bucketIndex = getBucketIndex(key);
LinkedList<HashNode> bucket = buckets[bucketIndex];
for (HashNode node : bucket) {
if (node.key.equals(key)) {
node.value = value;
return;
}
}
bucket.add(new HashNode(key, value));
size++;
}
public String get(String key) {
int bucketIndex = getBucketIndex(key);
LinkedList<HashNode> bucket = buckets[bucketIndex];
for (HashNode node : bucket) {
if (node.key.equals(key)) {
return node.value;
}
}
return null;
}
public String remove(String key) {
int bucketIndex = getBucketIndex(key);
LinkedList<HashNode> bucket = buckets[bucketIndex];
HashNode prev = null;
for (HashNode node : bucket) {
if (node.key.equals(key)) {
if (prev != null) {
prev.next = node.next;
} else {
bucket.remove(node);
}
size--;
return node.value;
}
prev = node;
}
return null;
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
}
// Main
public class Main {
public static void main(String[] args) {
HashTable hashTable = new HashTable();
hashTable.put("one", "1");
hashTable.put("two", "2");
hashTable.put("three", "3");
System.out.println("Value for key 'one': " + hashTable.get("one"));
System.out.println("Value for key 'two': " + hashTable.get("two"));
System.out.println("Removing key 'one': " + hashTable.remove("one"));
System.out.println("Contains key 'one': " + (hashTable.get("one") != null));
}
}
/*
μΆλ ₯
Value for key 'one': 1
Value for key 'two': 2
Removing key 'one': 1
Contains key 'one': false
*/