[자료구조 및 프로그래밍] 12. Hashing & Hash Table

2023. 12. 2. 22:15·CS/자료구조
반응형

자료구조와 탐색 시간

지금까지 자료구조를 정리하면서 주요하게 다뤘던 내용 중 하나는 바로 "탐색" 이었다.

그리고 원하는 자료를 탐색하기 위해 수행한 가장 근본적인 동작은 바로 키를 비교하는 것이었다.

어떤 키가 다른 키와 같은지 다른지, 혹은 큰 지 작은 지를 비교하여 원하는 값을 탐색해내갔다.

 

여기 3글자 알파벳 소문자로 이루어진 이름과 4개의 숫자 쌍을 저장하는 간단한 주소록 프로그램이 있다.

그리고 이 주소록 프로그램에서 주소록 정보를 BST를 이용해 저장한다고 해보자.

만약 1000개의 주소록 데이터를 BST에 저장한다면, 최적의 경우 BST의 높이는 log(1000) 이므로 대략 10이라고 할 수 있고, 최악의 경우의 높이는 대략 1000이 될 것이다.

또 평균적으로는 1000개의 데이터를 BST에 넣으면 20 미만의 높이를 갖는다.

이 말은, 우리가 데이터를 찾고, 추가하고, 삭제하는데 20번의 비교가 필요하다는 뜻이다.

그리고 당연하게도 BST에 넣는 주소록 데이터의 양이 늘어날 수록, 그에 비례해 탐색 시간 역시 증가한다.


해시

그런데, 오늘 정리할 hashing 을 이용하면 이상적인 상황에서 데이터가 얼마나 많이 늘어나는가에 상관 없이 데이터를 O(1) 즉, 단 한번의 연산으로 찾을 수 있다.

 

주소록 프로그램에서는 '이름' 이라는 키를 가지고 번호를 찾는다.

이제 그 '이름' 이라는 키로 가능한 모든 집합을 U 라고 해보자.

이름은 알파벳 소문자로 구성될 수 있으므로, 26^3 = 대략 20000 가지의 key가 존재한다.

 

h 라는 function 이 있다고 생각해보자.

이 function은 U 를 정의역으로 하며, 0부터 M-1 까지의 값을 공역으로 갖는다고 해보자.

우리는 이런 function 을 'hash function' 이라고 부르고, 0부터 M-1 사이의 값을 hash value 라고 부른다.

그리고 이를 h(k) 와 같이 쓸 수 있다.

 

다시 위 주소록 프로그램의 상황에 대해서 생각해보자.

만약 어떤 키값을 넣었을 때, 0부터 1999 사이의 값을 내는, (즉, M = 2000 ) 해시 함수를 가지고 있고, 모든 키값에 대해 해시함수의 결과값이 서로 다르게 나온다면, 우리는 2000사이즈 배열에 우리가 원하는 데이터를 모두 저장할 수 있다.

그리고 이 데이터에 접근할 때는 오직 해시 함수에 의한 해시 값 계산만큼의 시간밖에 걸리지 않는다.

 

그러나 실제로는 키값의 집합 U의 사이즈가 아주 큰 반면 해시함수가 내놓는 값의 범위는 비교적 좁아서, 어떤 두 키값 k1, k2 에 대해 h(k1) = h(k2) 가 되는 상황이 발생하는 경우가 많으며, 이런 경우를 '충돌' 이라고 한다.

 

그렇다면 보통 해시함수는 어떻게 구현할까?

좋은 해시함수는 빠르게 계산할 수 있으면서도, 충돌이 적게 일어나는 함수다.

'해시' 라는 말 자체가 어떤 덩어리를 잘게 잘게 썰어낸다는 의미가 있다 (해시 브라운의 그 해시도 그 뜻이다)

그래서 좋은 해시함수는 겹치지 않게 작은 조각으로 잘 조각내는 함수라고 할 수 있다.

 

보통 해시함수는 아래와 같은 형태를 자주 사용한다.

 

h(k) = k mod M

 

그리고 보통 M 값은 소수를 사용한다.

(합성수를 사용할 때보다 충돌 횟수가 꽤 크게 줄어든다.)

 

이 '해시'는 여러 곳에서 사용된다.

대표적으로 사용하는 것이 해시 테이블 (해시 맵) 과 Set 자료구조를 구현하는데 사용할 수 있다.

또 비밀번호를 평문이 아니라 해싱하여 저장하므로써, 외부 사람이 봤을 때 평문을 알 수 없게 하는 데에도 사용된다.


해시 충돌의 해결

해시는 이상적으로는 매우 좋은 자료구조이다.

임의의 데이터를 상수시간만에 찾아낼 수 있기 때문이다.

그렇지만 실제로는 '해시 충돌' 문제가 있어 이를 해결해야 한다.

 

해시 충돌을 해결하는 방법은 크게 2가지로 나누어 진다.

 

1. Chaining

2. Open Addressing

 

첫번째 방법인 체이닝은, 충돌이 일어나는 것 자체를 인정하고, 해시값에 해당하는 위치에 하나의 데이터를 저장하는 것이 아니라 '연결 리스트' 의 노드를 저장한다.

 

그래서 만약 어떤 해시값에 해당하는 데이터가 들어오면, 그 데이터를 연결 리스트에 차곡 차곡 추가하는 방식이다.

어떤 데이터를 찾을 때도, 키을 해싱한 값에 위치해있는 연결리스트를 순회하여 찾으면 된다.

 

두번째 방법인 open addressing 방식은, 해시충돌이 일어났을 때, 적당한 규칙을 가지고 그 값을 비어있는 다른 키값에 저장하는 것이다.

예를 들어 h(k) 위치에 이미 값이 있다면 h(k) + 1 위치나 h(k)-1 위치가 비어있을 때 이곳에 그냥 저장하는 방식이다.

값을 찾을 때도 h(k) 위치에 있는 값이 찾는 값과 다르다면 그 주변을 탐색하여 찾는 방식이다.


지금까지 Hashing 에 대하여 간단하게 정리해보았다.

다음 글에서는 파이썬의 dictionary 가 어떻게 구현되어 있는지, 해시를 쓰고 있다면 어떤 해시 함수를 사용하고 있는지 간단하게 살펴보려고 한다.

반응형
저작자표시 비영리 변경금지 (새창열림)

'CS > 자료구조' 카테고리의 다른 글

[자료구조 및 프로그래밍] 14. 정렬 (선택정렬, 삽입정렬, 퀵소트, 머지소트, 기수정렬)  (0) 2023.12.09
[자료구조 및 프로그래밍] 13. Binary Search & Sequential Search  (0) 2023.12.05
[자료구조 및 프로그래밍] 11.5. Python Heapq 모듈 뜯어보기  (2) 2023.12.02
[자료구조 및 프로그래밍] 11. 우선순위 큐와 Heap  (0) 2023.12.02
[자료구조 및 프로그래밍] 10. BST 탐색 시간과 Height 사이 관계  (0) 2023.10.23
'CS/자료구조' 카테고리의 다른 글
  • [자료구조 및 프로그래밍] 14. 정렬 (선택정렬, 삽입정렬, 퀵소트, 머지소트, 기수정렬)
  • [자료구조 및 프로그래밍] 13. Binary Search & Sequential Search
  • [자료구조 및 프로그래밍] 11.5. Python Heapq 모듈 뜯어보기
  • [자료구조 및 프로그래밍] 11. 우선순위 큐와 Heap
에버듀
에버듀
개발은 좋은데 뭘로 개발할까
  • 에버듀
    Blog. 에버듀
    에버듀
  • 전체
    오늘
    어제
    • 분류 전체보기 (615) N
      • 개인 프로젝트 (43)
        • 토이 프로젝트 (3)
        • [2020] 카카오톡 봇 (9)
        • [2021] 코드악보 공유APP (22)
        • [2022] 유튜브 뮤직 클론코딩 (9)
        • [2025] 한글 SQL 데이터베이스 (0)
      • 팀 프로젝트 (22)
        • [2020] 인공지능 숫자야구 (4)
        • [2022] OSAM 온라인 해커톤 (10)
        • [2024] GDSC 프로젝트 트랙 (6)
        • [2025] 큰소리 웹 페이지 (2)
      • CS (335)
        • 자료구조 (19)
        • 어셈블리 (41)
        • 멀티미디어응용수학 (7)
        • 컴퓨터 구조 (29)
        • 알고리즘 분석 (4)
        • 컴퓨터 네트워크 (38)
        • 프로그래밍언어론 (15)
        • HCI 윈도우즈프로그래밍 (26)
        • 기초데이터베이스 (29)
        • 운영체제 (23)
        • 오토마타 (24)
        • 문제해결기법 (11)
        • 블록체인 (22)
        • 소프트웨어공학 (21)
        • 기계학습심화 (12)
        • 컴퓨터그래픽스와 메타버스 (8)
        • 분산시스템특론 (6)
      • 자기계발 (45) N
        • 생각 정리 (23) N
        • 대외활동 (11)
        • 동아리 (7)
        • 자격증 (3)
        • 머니 스터디 (1)
      • 알고리즘 (PS) (107)
        • BOJ (101)
        • Programmers (5)
        • 알고리즘 이모저모 (1)
      • WEB(BE) (8)
        • express.js (1)
        • Spring & Spring Boot (7)
      • WEB(FE) (2)
        • html, css, js (1)
        • React.js (1)
      • Tool & Language (6)
        • Edit Plus (1)
        • Git (1)
        • Python3 (2)
        • Java (2)
      • Infra (12)
        • AWS (1)
        • Oracle Cloud (8)
        • Firebase (2)
        • Network (1)
      • Android (18)
        • Java (6)
        • Flutter (12)
      • Window (2)
        • Visual Studio 없이 WPF (1)
        • MFC (1)
      • 독서 (14)
        • Inside Javascript (7)
        • Database Internals (6)
        • 한 글 후기 (1)
  • 링크

    • github
    • website
  • 인기 글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
에버듀
[자료구조 및 프로그래밍] 12. Hashing & Hash Table
상단으로

티스토리툴바