CS공부 - 자료구조 - 3

soonrok·2023년 1월 19일
0

CS

목록 보기
3/7
post-thumbnail

Hash Table

  • 내부적으로 배열을 사용해 데이터를 저장해 빠른 검색속도를 가진 자료구조
  • 특정 값을검색하는데 데이터의 고유한 인덱스로 접근하기 때문에 평균적인 경우(Collision이 일어나지 않는 경우) O(1)의 시간 복잡도를 갖는다.
  • 이해를 위해 다음 사진을 참고하자.

Hash Funtion

  • '특별한 알고리즘'를 이용해 데이터의 고유한 인덱스를 Hash Code로 변환하는데 이 '특별한 알고리즘'을 Hash Method, Hash Function이라고 한다.
  • 어설픈 Hash Function을 사용하면 동일한 Hash Code가 생성될 수 있는데 이것을 Collision(충돌)이라고 한다.
  • 그럼 좋은 Hash Function은 어떤 조건을 가지고 있을까?
    • key의 일부분이 아니라 전체를 이용해 Hash 값을 만들어낸다.
    • key가 어떤 특성을 가지고 있는지에 따라 달라진다.
    • Collision을 최소화하는 방향으로 설계되며, 발생했을때 어떻게 대응할 것인지도 중요하다.
  • Collision이 많아질수록 O(1)에 해당하던 접근(Search)의 시간 복잡도가 O(n)에 가까워진다.

Collision의 해결

Open Address (개방 주소법)

  • Collision이 발생하면 다른 Hash Bucket에 데이터를 추가한다.
    • Hash Bucket(Hash Slot): 데이터를 저장하는 공간를 가리키는 용어
  • 다른 Hash Bucket를 찾는 방법은 크게 3가지로 다음과 같다.
    • Linear Probing: 순차적으로 다음 Hash Bucket을 탐색해 비어있는 공간을 찾는다.
    • Quadratic Probing: n^2칸씩(1, 4, 9, ...) 뛰어넘어 Hash Bucket을 탐색해 비어있는 공간을 찾는다.
    • Double Hashing Probing: 또 다른 2차 Hash Function을 이용해 새로운 주소를 할당하는데, Linear와 Quadratic에 비해 연산량이 많아진다.

Separate Chaining (분리 연결법)

  • 일반적으로 개방 주소법에 비해 빠르다.
  • Collision이 일어나지 않도록 해시 보조 함수를 사용한다.
  • Java 7에서 이 방식을 이용해 Hash Map을 제공한다.
  • 두 가지 구현 방식이 존재하는데 다음과 같다.
    • Linked List: 각각의 버킷을 연결 리스트로 만들어 Collision이 발생하면 해당 리스트에 추가한다.
    • Tree: 각각의 버킷을 트리로 만들어 Collision이 발생하면 해당 리스트에 추가한다.
  • 두 가지 방식중 하나를 택하는 기준은 저장되는 데이터의 개수로 6과 8이 그 기준이다. (적을 때 Linked List, 많을 때 Tree)
  • 7이 없는 이유는 Linked List와 Tree로의 변환이 빈번하게 일어나는 것을 막기 위함이다. (6개일때 하나가 추가되면 아직 Linked List 유지, 8개일때 하나가 삭제되면 아직 Tree 유지)

두 방식의 비교

  • 두 방식 모두 Worst Case에서의 시간 복잡도는 O(M)이다.
  • Open Address 방식이 Separate Chaining 방식에 비해 데이터 캐시 효율이 높다. 따라서 데이터의 개수가 충분히 적은 경우 Open Address 방식의 성능이 더 좋다.
  • Separate Cheining 방식이 Open Address 방식에 비해 테이블 확장이 느리게 일어난다.

테이블 확장

  • Hash Table에서 데이터의 개수가 일정수준을 넘어가게 되면 테이블의 크기를 2배로 늘리게 되는데 이를 테이블 확장이라고 한다.
  • 일정수준은 테이블의 75%에 해당하며 이 0.75를 Load Factor라고 부른다.
profile
I Will be Relaxed Person

0개의 댓글