▼ 비선형 자료 구조 - 그래프
와 트리
에 대한 내용
[CS] 자료 구조의 분류 - 비선형 자료 구조 #1 (그래프, 트리)
▼ 비선형 자료 구조 - 힙
, 우선순위 큐
에 대한 내용
[CS] 자료 구조의 분류 - 비선형 자료 구조 #2 (힙, 우선순위 큐)
키(key)
와 매핑된 값(value)
의 조합으로 형성된 자료 구조, 즉 Key와 Value를 쌍으로 데이터를 저장하는 자료 구조이다.'key' : 1
과 같이 string : int
형태로 값을 할당해야 할 때, 해시 테이블(Hash Table)을 구현할 때 등 사용한다.해시 맵 (Hash Map 또는 Hash Table)
C++ STL의 Map
Java의 Map 인터페이스
Python의 딕셔너리(Dictionary)
📌 삽입 (Insertion)
set(key, value)
: 새로운 키-값 쌍을 Map에 추가한다. 만약 이미 동일한 키가 존재하면 해당 키의 값을 갱신한다.const myMap = new Map();
myMap.set('name', 'John');
myMap.set('age', 30);
📌 검색 (Lookup)
get(key)
: 특정 키에 연결된 값을 검색한다.const name = myMap.get('name'); // 'John'
📌 삭제 (Deletion)
delete(key)
: 특정 키-값 쌍을 삭제한다.myMap.delete('age'); // 삭제
📌 크기 (Size)
size
: Map에 저장된 키-값 쌍의 개수를 반환한다.const size = myMap.size; // 1 (age 키가 삭제되었으므로 1개의 키-값 쌍만 남음)
📌 존재 여부 확인 (Existence Check)
has(key)
: 특정 키가 Map 내에 존재하는지 확인한다.const hasName = myMap.has('name'); // true
const hasAge = myMap.has('age'); // false
📌 키 목록 및 값 목록 검색 (Key and Value Retrieval)
keys()
: Map 내의 모든 키의 목록을 반환한다.values()
: Map 내의 모든 값을 반환한다.entries()
: Map 내의 모든 키-값 쌍을 [key, value] 형태의 배열로 반환한다.const keys = Array.from(myMap.keys()); // ['name']
const values = Array.from(myMap.values()); // ['John']
const entries = Array.from(myMap.entries()); // [['name', 'John']]
📌 모든 요소 제거 (Clear)
clear()
: Map 내의 모든 키-값 쌍을 제거한다.myMap.clear(); // 모든 키-값 쌍 제거
📌 반복 (Iteration)
for...of
와 forEach
메서드를 활용하여 Set 순회const myMap = new Map();
myMap.set('name', 'John');
myMap.set('age', 30);
myMap.set('city', 'New York');
// for...of 반복문을 사용하여 Map 순회
for (const [key, value] of myMap) {
console.log(`${key}: ${value}`);
}
// forEach 메서드를 사용하여 Map 순회
myMap.forEach((value, key) => {
console.log(`${key}: ${value}`);
});
📌 삽입 (Insertion)
add(value)
: Set에 새로운 값을 추가합니다. 이미 Set에 존재하는 값을 추가하더라도 중복 값은 저장되지 않습니다.const mySet = new Set();
mySet.add(1);
mySet.add(2);
mySet.add(3);
console.log(mySet); // Set { 1, 2, 3 }
📌 삭제 (Deletion)
delete(value)
: Set에서 지정된 값을 삭제합니다. 삭제가 성공하면 true를 반환하고, 삭제할 요소가 없으면 false를 반환합니다.const mySet = new Set([1, 2, 3]);
mySet.delete(2); // 삭제 성공, true 반환
mySet.delete(4); // 삭제 실패 (요소가 없음), false 반환
console.log(mySet); // Set { 1, 3 }
📌 크기 (Size)
size
또는 length
프로퍼티: Set의 요소 개수를 반환합니다.const mySet = new Set([1, 2, 3]);
console.log(mySet.size); // 3
📌 존재 여부 확인 (Existence Check)
has(value)
: Set에 지정된 값을 가지고 있는지 확인합니다. 존재하면 true를, 존재하지 않으면 false를 반환합니다.const mySet = new Set([1, 2, 3]);
console.log(mySet.has(2)); // true
console.log(mySet.has(4)); // false
📌 모든 요소 제거 (Clear)
clear()
: Set의 모든 요소를 삭제하여 빈 Set으로 만듭니다.const mySet = new Set([1, 2, 3]);
mySet.clear();
console.log(mySet); // Set {}
📌 반복 (Iteration)
for...of
와 forEach
를 활용하여 Map 순회// for...of 반복문을 사용하여 Map 순회
const mySet1 = new Set(['apple', 'banana', 'cherry']);
for (const item of mySet1) {
console.log(item);
}
// 출력:
// 'apple'
// 'banana'
// 'cherry'
// forEach 메서드를 사용하여 Map 순회
const mySet2 = new Set([1, 2, 3]);
mySet2.forEach((value) => {
console.log(value);
});
// 출력:
// 1
// 2
// 3
Set과 배열(Array)은 모두 값(데이터)의 컬렉션을 저장하는 자료 구조이지만, 몇 가지 중요한 차이점이 있다.
중복 요소의 처리
요소 순서
인덱싱
반복
메서드 및 기능
셋(Set)
add(value)
: O(1) (해시 함수를 사용하므로 해시 충돌이 적으면 O(1)이다.)delete(value)
: O(1)has(value)
: O(1)size 또는 length
: O(1)배열(Array)
push(value)
: O(1) (배열의 크기가 동적으로 조정되면 O(N)의 복잡도가 발생할 수 있다.)pop()
: O(1)shift()
: O(N) (모든 요소를 앞으로 이동해야 하므로)unshift(value)
: O(N) (모든 요소를 뒤로 밀어야 하므로)splice()
: O(N) (삭제 또는 삽입하는 요소의 수에 따라 다르다.)👉🏻 따라서 Set은 요소 추가, 삭제 및 확인 연산에서 일반적으로 상수 시간 복잡도 O(1)을 가지므로, 중복 요소를 허용하지 않고 요소 존재 여부를 빠르게 확인하는 데 적합하다.
👉🏻 배열은 요소의 순서가 중요하거나 동적 크기 조정이 필요한 경우에 유용하다. 예를 들어, 인덱스를 사용하여 특정 요소에 직접 접근하거나 요소를 정렬하거나 필터링하는 경우 배열이 유용하다.
Division Method (나눗셈 방법): 이 방법은 키를 테이블 크기로 나눈 나머지를 해시 코드로 사용한다. 즉, hash(key) = key % table_size
와 같은 형태로 표현된다. 이 방법은 간단하고 빠르지만, 특정 키 패턴에 대해서는 충돌이 발생할 수 있다.
Multiplication Method (곱셈 방법): 이 방법은 키를 0과 1 사이의 실수로 변환한 다음 테이블 크기를 곱한 후 정수 부분을 취한다. hash(key) = floor(table_size * (key * A - floor(key * A)))
와 같은 형태로 표현된다. 상수 A는 일반적으로 0보다 크고 1보다 작은 값을 사용한다. 이 방법은 좋은 분포를 제공하는데, 충돌을 최소화하는 데 도움이 된다.
Folding Method (접기 방법): 이 방법은 키를 일정한 크기의 부분 키로 나누고 이를 합하여 해시 코드를 생성한다. 예를 들어, 123456789을 12, 34, 56, 78, 9로 나누고 합쳐서 해시 코드를 생성할 수 있다.
Mid-Square Method (중앙제곱 방법): 이 방법은 키를 제곱한 다음 중간 일부 자리를 선택하여 해시 코드로 사용한다. 예를 들어, 1234를 제곱하면 1522756이고, 여기서 중간의 3자리인 227을 해시 코드로 사용할 수 있다.
SHA-1, SHA-256 등 암호학적 해시 함수: 보안이 중요한 경우, 암호학적 해시 함수를 사용할 수 있다. 이러한 함수는 충돌을 최소화하고, 무작위성과 안전성을 제공합니다. 하지만 일반적인 해시 테이블에 비해 계산 비용이 높을 수 있다.
O(1)
, 최악: O(N)
O(1)
의 시간복잡도로 데이터를 조회할 수 있다.O(N)
까지 시간복잡도가 증가할 수 있다.Reference.