이 영역을 누르면 첫 페이지로 이동
lucid_dream 블로그의 첫 페이지로 이동

lucid_dream

페이지 맨 위로 올라가기

lucid_dream

다양한 상상을 현실로 만드는 멀티 크리에이터를 꿈꾸고 있습니다 ❤️

해시 테이블 (Hash Table)

  • 2021.11.01 06:13
  • 💻 컴퓨터공학/자료구조
글 작성자: NoHack
728x90

Hash Table

해시 테이블(Hash Table)은 데이터의 해시 값을 키로 사용한 데이터 집합을 말합니다. 해시는 데이터를 새로운 형태로 변환한다는 의미를 가지고 있으며, 주어진 키를 미리 구현한 해시 함수를 통해 변환합니다. 해시 테이블은 해싱 된 키를 통해 데이터에 바로 접근할 수 있으므로, 매우 빠른 탐색 속도를 갖고 있습니다.

해싱 함수에 일반적으로 사용되는 방법은 다음과 같습니다.

  • 나눗셈법: 키 값을 테이블의 사이즈로 나눈 후의 나머지를 주소로 사용하는 방법
  • 자릿수 접기: 문자열 키 값의 자리마다 정해진 아스키 코드를 합친 값을 주소로 사용하는 방법

해시 테이블을 사용할 때는 충돌(Collision)과 클러스터링(Clustering)을 방지해야 합니다. 충돌은 말 그대로 동일한 해시 값이 만들어져 충돌이 발생하는 것이고, 클러스터링은 데이터가 한 곳에 몰리는 현상을 말합니다. 본문에서는 충돌을 해결하는 여러 방법 중 하나인 체이닝(Chaining)에 대해서만 소개합니다. 체이닝은 동일한 해시 값이 만들어져 충돌이 발생하면, 해당 위치를 링크드 리스트로 만들어 같은 해시 값을 가진 데이터들이 서로 연결되도록 합니다. 다만 이 경우에 충돌을 해결할 수는 있지만, 리스트가 순차 탐색을 하는 만큼 속도가 느려지게 됩니다.

노드 & 해시 테이블

function Node(key, data) {
  this.key = key;
  this.data = data;
  this.next = null;
}

function HashTable(size) {
  Array.call(this);
  this.size = size;
}
HashTable.prototype = Object.create(Array.prototype);
HashTable.prototype.constructor = HashTable;

해시 테이블을 배열처럼 사용하기 위해 배열의 프로토타입을 상속 받도록 구현했습니다. 그리고 해시 테이블의 크기를 해싱 알고리즘에 사용할 계획이기에 HashTable 생성자에서 매개변수로 size를 받도록 했습니다.

해싱 함수

HashTable.prototype.hash = function (key, keylen) {
  let hash = 0;
  for (let i = 0; i < keylen; i++) {
    hash = hash + key[i].charCodeAt(0);
  }
  return hash % this.size;
};

해싱(Hashing)은 로직을 통해 키(인덱스) 값을 결정하는 작업입니다. 해싱에 사용하는 알고리즘은 다양하지만, 본문에서는 위에서 언급한 자릿수 접기를 사용해 구현했습니다.

데이터 추가 & 획득

HashTable.prototype.set = function (key, value) {
  const addr = this.hash(key, key.length);
  const newNode = new Node(key, value);

  if (this[addr] === undefined) {
    this[addr] = newNode;
  } else {
    let temp = this[addr];
    newNode.next = temp;
    this[addr] = newNode;

    console.log(`충돌 발생: Key(${key}), Address(${addr})`);
  }
};

HashTable.prototype.get = function (key) {
  const addr = this.hash(key, key.length);

  if (this[addr] === undefined) {
    return null;
  }
  let current = this[addr];
  while (true) {
    if (current.key === key) {
      return current.data;
    }
    if (current.next === null) return null;
    else current = current.next;
  }
};

데이터를 추가하고 획득하는 두 함수는 해싱 함수를 통해 참조할 인덱스를 계산합니다. 체이닝은 링크드 리스트를 활용한 것이므로, 코드 자체가 어렵지는 않아 해시 중복(충돌)이 발생한 경우에 대해서만 설명하겠습니다. 중복 발생 시 set 함수에서는 리스트의 헤드를 교체하는 식으로 처리했고, get 함수에서는 순차적으로 리스트를 순회하며 key를 비교해 일치하는 데이터를 뽑을 수 있도록 했습니다.

References 📝

본문의 내용은 GeeksforGeeks의 자료구조 튜토리얼을 참고해 작성했습니다 ❤️
저작자표시 비영리 동일조건 (새창열림)

'💻 컴퓨터공학 > 자료구조' 카테고리의 다른 글

그래프 (Graph)  (0) 2021.11.01
우선순위 큐 (Priority Queue)  (0) 2021.10.30
힙 (Heap)  (0) 2021.10.29
분리 집합 (Disjoint Set)  (0) 2021.10.26
수식 트리 (Expression Tree)  (0) 2021.10.26

댓글

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • 그래프 (Graph)

    그래프 (Graph)

    2021.11.01
  • 우선순위 큐 (Priority Queue)

    우선순위 큐 (Priority Queue)

    2021.10.30
  • 힙 (Heap)

    힙 (Heap)

    2021.10.29
  • 분리 집합 (Disjoint Set)

    분리 집합 (Disjoint Set)

    2021.10.26
다른 글 더 둘러보기

정보

lucid_dream 블로그의 첫 페이지로 이동

lucid_dream

  • lucid_dream의 첫 페이지로 이동

검색

메뉴

  • All categories
  • About me
  • Guest Book

카테고리

  • 분류 전체보기 (122)
    • 💦 일상뻘글 (1)
    • ⭐️ 프로젝트 (7)
      • 사이드 프로젝트 (1)
      • 스터디 노트 (6)
    • 🌈 기술스택 (31)
      • Web Basic (10)
      • JavaScript (14)
      • React (0)
      • Git (7)
    • 💻 컴퓨터공학 (28)
      • 자료구조 (13)
      • 알고리즘 (7)
      • 운영체제 (4)
      • 소프트웨어 공학 (4)
    • 📝 문제풀이 (55)
      • 프로그래머스 (55)
      • 과제관 (0)
    • 🐹 취미생활 (0)
      • Film Log (0)
      • Cover Song (0)

댓글

정보

NoHack의 lucid_dream

lucid_dream

NoHack

나의 외부 링크

  • Github
  • Instagram

블로그 구독하기

  • 구독하기
  • RSS 피드

방문자

  • 전체 방문자
  • 오늘
  • 어제

티스토리

  • 티스토리 홈
  • 이 블로그 관리하기
  • 글쓰기
Powered by Tistory / Kakao. Copyright © NoHack.

티스토리툴바