해시 테이블(hash table)

상위문서 : 자료구조

필수참고문서 : 연결리스트


목차

1. 개요
2. 설명
3. 충돌문제
4.구현
4.1. JAVA로 구현
4.2. C#으로 구현


1.개요

해시테이블은 임의의 길이를 갖는 임의의 데이터를 기준으로 키를 값에 매핑할 수 있는 구조의 자료구조다.

2.설명

요즘은 휴대폰 전화번호가 xxx-oooo-rrrr 구조로 되어있다. 통신사에서는 저 모든 번호를 미리 지정해두고 새롭게 가입한 사람이 남는 번호중에 선택하는 것일까? 아니다 그럴경우 저 모든 번호를 위한 저장공간은 앞에 xxx가 고정되어있다고 쳐도 뒤에 8자리는 0~9까지 10개의 번호가 각자리에 들어갈 수 있는데 그러면 10^8개 즉 1억개의 번호를 미리 만들어 둬야한다. 이것은 너무 큰 저장공간의 낭비이다. 그리고 알고있듯이 아무리 뛰어난 알고리즘이라도 찾는 번호의 수가 많으면 그만큼 그 번호를 찾는데 엄청난 시간이 걸린다. 생각해보라 전화를 하려고 연결하면 1분뒤에 통화되는 끔찍한 상황을 그러면 이렇게 하는 것은 어떨까? 가입자가 새로 생길때마다 빈 데이터베이스에 새롭게 정보를 추가하는것이다. 이러면 저장공간의 낭비문제는 해결했다. 생각을 더 발전해서 굳이 oooo-rrrr 이 전부를 써서 번호를 대조해서 찾을 필요가 있을까?? 예를 들어 oooo만으로도 번호를 식별할 수 있을 지도 모른다. 실제로 번호들이 겹치는 경우는 의외로 겹치는 적다.(7777,1004 이런건 예외다…) 여기서 겹치는 경우가 적다는 것은 고르게 분포되어 있다는 뜻이 된다. 해시 테이블은 데이터의 일부정보만으로 빠르게 데이터를 탐색하는 자료구조이다.

3. 충돌문제

그런데 만약에 통신사에 가입한 회원이 10001명(일만 일명)이라고 생각하자 중간번호는 oooo로 10^4 즉 0000~9999까지 만개의 번호가 있다. 아무리 통신사에 가입된 회원의 번호가 매우 균등하게 있어도 최소 어떤 한 번호는 2명이 쓰고 있는것이 된다. 이것을 충돌문제라고 한다. 원리 자체는 이산수학의 비둘기 집의 원리 문제가 된다. 해시 테이블을 구현할 때는 이러한 충돌문제에 대해서 대처할 수 있는 방법이 필요하다. 충돌문제를 대처하기 위해서 다음 두 알고리즘을 소개한다.

1. 선형 조사법
해시테이블의 크기가 들어가는 원소의 갯수보다 클 때 사용하는 알고리즘이다. 동일 주소에 해시되는 원소가 있으면, 그 동일 주소를 기준으로 오른쪽으로 한칸씩 이동하면서 비어있으면 넣고 비어있지 않으면 또 옆으로 가서 비어있으면 넣고 비어있지 않으면 또 옆으로가서...... 이런 알고리즘을 선형 조사법이라고 한다.  선형 조사법의 문제는 해시 테이블에서 할당된 공간이 연속해서 나오면 새로운 값을 넣을 때 그 주변으로 값이 배정될 경우 충돌이 계속일어나 결국 그 주변에 쌓여버리는 이름바 집적화 현상이 발생할 수 있다.

선형 조사법의 알고리즘을 생성할 때는 넣는 값을 해시 테이블의 크기로 나누기하여 나머지 값을 키값으로 사용한다.

2. 이중 해싱
이중 해싱은 위의 선형 조사법처럼 집적화가 발생하지 않는 방법이다. 이 알고리즘은 해시 값을 만들때 함수를 두개 쓰는데 첫번째 함수를 f1 두번째 함수를 f2라고 하겠다.
먼저 f1은 선형 탐사법의 해시 생성 함수와 같이 값을 배열의 크기로 나눠 나머지를 해시 값으로 쓴다. 여기서 이 해시 값에 이미 먼저 온 손님(?)이 있을 경우 f2함수로 해시 값을 생성하여 두번 째 함수의 해시값에 넣는다. 따라서 f1과 f2의 함수는 넣는 값에 대해서 다른 해시 값을 보장해야한다. 

4. 구현

구현은 맵으로 구현을 한다.

on 2017년 6월 6일 화요일 | A comment?
0 responses to “해시 테이블(hash table)”

Leave a Reply

최근 많이 본 글