해싱은 키 값을 기반으로 특정 테이블의 인덱스를 계산하여 빠르게 데이터를 저장하고 검색할 수 있는 방법입니다. 하지만 해싱에는 충돌(Collision) 문제가 발생할 수 있습니다. 충돌은 서로 다른 키 값이 동일한 해시 주소로 매핑될 때 발생합니다. 이를 해결하기 위한 여러 가지 기법이 있습니다.
이번 글에서는 선형 조사법(Linear Probing), 이차 조사법(Quadratic Probing), 이중 해싱법(Double Hashing), 체인법(Chaining)에 대해 설명하겠습니다.
오버플로우(Overflow): 충돌이 발생하고 나서 더 이상 빈 공간이 없을 때 발생하는 문제입니다. 이 경우, 해시 테이블에 더 이상 항목을 저장할 수 없게 됩니다.
선형 조사법 코드 예시:
#include <stdio.h>
int i, k, n = 8;
int hash(int key) {
return key % n;
}
int main() {
int key;
int list[8] = {0, 0, 10, 3, 2, 5, 0, 0};
scanf("%d", &key);
int index = hash(key);
while(1) {
if(list[index] == 0) {
list[index] = key;
break;
} else {
k++;
index = (hash(key) + k) % n;
}
}
printf("%d", index);
return 0;
}
클러스터링: 충돌이 발생하면 해당 버킷에서만 탐색이 이루어지기 때문에 충돌이 잦을 경우, 특정 구역에 데이터가 몰리는 현상이 발생할 수 있습니다.
이차 조사법 코드 예시:
#include <stdio.h>
int i, k, n = 8;
int hash(int key) {
return key % n;
}
int doublehash(int key) {
if(key > 20) return 4;
else return 5;
}
int main() {
int key;
int list[8] = {0, 0, 10, 3, 2, 5, 0, 0};
scanf("%d", &key);
int index = hash(key);
while(1) {
if(list[index] == 0) {
list[index] = key;
break;
} else {
k++;
index = (hash(key) + doublehash(key) * k) % n;
}
}
printf("%d", index);
return 0;
}
클러스터링 완화: 선형 조사법보다 충돌을 처리하는 방식이 다르므로 클러스터링 문제를 덜 일으킵니다.
이중 해싱법은 클러스터링 문제를 매우 효과적으로 해결할 수 있으며, 다른 충돌 해결 방법들에 비해 매우 효율적입니다.
이중 해싱법 코드 예시:
#include <stdio.h>
int i, k, n = 8;
int hash(int key) {
return key % n;
}
int doublehash(int key) {
if(key > 20) return 4;
else return 5;
}
int main() {
int key;
int list[8] = {0, 0, 10, 3, 2, 5, 0, 0};
scanf("%d", &key);
int index = hash(key);
while(1) {
if(list[index] == 0) {
list[index] = key;
break;
} else {
k++;
index = (hash(key) + doublehash(key) * k) % n;
}
}
printf("%d", index);
return 0;
}
효율성: 충돌이 발생해도 두 번째 해시 함수를 이용해 더 적절한 인덱스를 찾을 수 있기 때문에 선형 조사법이나 이차 조사법보다 성능이 좋습니다.
체인법의 장점:
충돌 처리: 충돌이 발생해도 연결 리스트로 해결하므로 성능이 크게 저하되지 않습니다.
유연성: 버킷 크기에 제한이 없고, 동적 할당이 가능하므로 적은 공간으로도 많은 데이터를 처리할 수 있습니다.
충돌 해결 기법에는 여러 가지 방법이 있으며, 각 기법은 상황에 맞는 장단점이 존재합니다. 선형 조사법은 간단하지만 클러스터링 문제를 일으킬 수 있고, 이차 조사법과 이중 해싱법은 그 문제를 어느 정도 해결할 수 있습니다. 체인법은 가장 유연한 방법으로, 충돌을 해결하면서 성능을 유지할 수 있는 좋은 선택입니다. 각 방법을 잘 이해하고, 사용하는 해시 테이블의 성격에 맞게 적절한 방법을 선택하는 것이 중요합니다.