해시 테이블
- 해시 테이블은 ‘연결 리스트의 배열’
- 여러 값들을 몇 개의 바구니에 나눠 담는 상황을 생각해 보자.
- 각 값들은 ‘해시 함수’라는 맞춤형 함수를 통해서 어떤 바구니에 담기는 지가 결정된다.
- 각 바구니에 담기는 값들은 그 바구니에서 새롭게 정의되는 연결 리스트로 이어진다.
- 이와 같이 연결 리스트가 담긴 바구니가 여러개 있는 것이 ‘연결 리스트의 배열’, 즉 ‘해시 테이블’
쉬운 예로 아래 그림과 같이 사람의 이름이 해시 테이블에 저장되며, 해시 함수는 ‘이름의 가장 첫 글자’인 경우를 생각해 보자.
그 경우 알파벳 개수에 해당하는 총 26개의 포인터들이 있을 수 있으며, 각 포인터는 그 알파벳을 시작으로 하는 이름들을 저장하는 연결 리스트를 가리키게 된다.
- 만약 해시 함수가 이상적이라면, 각 바구니에는 단 하나의 값들만 담기게 될 것
- 따라서 검색 시간은 O(1)
- 하지만 최악의 상황에는 단 하나의 바구니에 모든 값들이 담겨서 O(n)이 될 수도 있다.
- 일반적으로는 최대한 많은 바구니를 만드는 해시 함수를 사용하기 때문에 거의 O(1)에 가깝다고 볼 수 있다.
트라이
- 트라이’는 기본적으로 ‘트리’ 형태의 자료 구조
- 특이한 점은 각 노드가 ‘배열’로 이루어져있다는 것입니다.
- 예를 들어 영어 알파벳으로 이루어진 문자열 값을 저장한다고 한다면 이 노드는 a부터 z까지의 값을 가지는 배열
- 그리고 배열의 각 요소, 즉 알파벳은 다음 층의 노드(a-z 배열)를 가리킨다.
아래 그림과 같이 Hermione, Harry, Hagrid 세 문자열을 트라이에 저장해보면,
루트 노드를 시작으로 각 화살표가 가리키는 알파벳을 따라가면서 노드를 이어주면 된다.
- 위와 같은 트라이에서 값을 검색하는데 걸리는 시간은 ‘문자열의 길이’에 의해 한정
- 단순히 문자열의 각 문자를 보며 트리를 탐색해나가기만 하면 되기 때문
- 일반적인 영어 이름의 길이를 n이라고 했을 때, 검색 시간은 O(n)이 되지만, 대부분의 이름은 그리 크지 않은 상수값(예, 20자 이내)이기 때문에 O(1)이나 마찬가지라고 볼 수 있다.
그 외 자료구조
① 큐
- 큐는 메모리 구조에서 살펴봤듯이 값이 아래로 쌓이는 구조
- 값을 넣고 뺄 때 ‘선입 선출’ 또는 ‘FIFO’라는 방식을 따르게 된다. 가장 먼저 들어온 값이 가장 먼저 나가는 것
- 은행에서 줄을 설 때 가장 먼저 줄을 선 사람이 가장 먼저 업무를 처리하게 되는 것과 동일
- 배열이나 연결 리스트를 통해 구현 가능
② 스택
- 반면 스택은 역시 메모리 구조에서 살펴봤듯이 값이 위로 쌓이는 구조
- 따라서 값을 넣고 뺄 때 ‘후입 선출’ 또는 ‘LIFO’라는 방식을 따르게 된다. 가장 나중에 들어온 값이 가장 먼저 나가는 것
- 뷔페에서 접시를 쌓아 뒀을 때 사람들이 가장 위에 있는(즉, 가장 나중에 쌓인) 접시를 가장 먼저 들고 가는 것과 동일
- 역시 배열이나 연결 리스트를 통해 구현 가능
③ 딕셔너리
- 딕셔너리는 ‘키’와 ‘값’이라는 요소로 이루어져 있다.
- ‘키’에 해당하는 ‘값’을 저장하고 읽어오는 것. 마치 대학교에서 ‘학번’에 따라서 ‘학생’이 결정되는 것과 동일
- 일반적인 의미에서 ‘해시 테이블’과 동일한 개념이라고도 볼 수 있다.
- ‘키’를 어떻게 정의할 것인지가 중요
'boostcourse > CS50' 카테고리의 다른 글
CS50 6. 자료구조(1) - 배열의 크기 조정하기, 연결 리스트 (0) | 2022.10.25 |
---|---|
CS50 5. 메모리(4) - 파일 쓰기, 파일 읽기 (0) | 2022.10.25 |
CS50 5. 메모리(3) - 메모리 할당과 해제/ 메모리 교환, 스택, 힙 (0) | 2022.10.25 |
CS50 5. 메모리(2) - 문자열, 문자열 비교, 문자열 복사 (0) | 2022.10.24 |
CS50 5. 메모리(1) - 메모리 주소, 포인터 (0) | 2022.10.24 |