Set(세트, 셋) 자료 구조
컬렉션 프레임워크 - Set
Collection 인터페이스
Collection
인터페이스는 자바에서 다양한 컬렉션, 즉 데이터 그룹을 다루기 위한 메서드를 정의한다. Collection
인터페이스는 List
, Set
, Queue
와 같은 다양한 하위 인터페이스와 함께 사용되며, 이를 통해 데이터를 리스트, 세트, 큐 등의 형태로 관리할 수 있다.
Set 인터페이스
자바의 Set
인터페이스는 중복을 허용하지 않는 유일한 요소의 집합을 나타낸다. 즉, 어떤 요소도 같은 Set
내에 두 번 이상 나타날 수 없다. Set
은 수학적 집합 개념을 구현한 것으로 순서를 보장하지 않으며, 특정 요소가 집합에 있는지 여부를 확인하는데 최적화되어있다.
HashSet
의 주요 연산(추가, 삭제, 검색)은 평균적으로 O(1)
의 시간 복잡도를 가진다.LinkedHashSet
은 HashSet
에 연결리스트를 추가해서 요소들의 순서를 유지한다.LinkedHashSet
도 HashSet
과 마찬가지로 평균 O(1)
시간 복잡도를 가진다.HashSet
보다는 조금 더 무겁다.TreeSet
은 이진 탐색 트리를 개선한 레드-블랙 트리를 내부에서 사용한다.O(log N)
의 시간 복잡도를 가진다. HashSet
보다는 느리다.총 15개의 데이터가 들어 있다. 여기서 숫자 35를 검색한다고 가정하면 총 4번의 계산이 수행된다. 이것은 O(N)
인 리스트 검색보다는 빠르고 O(1)
인 해시 검색보다는 느리다.
이진 탐색 트리와 성능
이렇게 오른쪽으로 치우친 편향 이진 트리의 경우 데이터의 수만큼 15를 찾는다고 하면 5번 검색을 해야 한다. 최악의 경우 O(N)
이 나온다.
이진 탐색 트리 개선
앞서 중간에 있는 6을 기준으로 다시 정렬한다. AVL 트리, 레드-블랙 트리 같은 균형을 맞추는 다양한 알고리즘이 존재한다. 자바의 TreeSet
은 레드-블랙 트리를 사용해서 균형을 지속해서 유지한다. 따라서 최악의 경우에도 O(log N)
의 성능을 제공한다.
이진 탐색 트리의 핵심은 입력 순서가 아니라 데이터의 값을 기준으로 정렬해서 보관한다는 점이다. 따라서 정렬된 순서로 데이터를 차례로 조회할 수 있다.
public class JavaSetMain {
public static void main(String[] args) {
run(new HashSet<String>());
run(new LinkedHashSet<String>());
run(new TreeSet<String>());
}
private static void run(Set<String> set) {
System.out.println("set = " + set.getClass());
set.add("C");
set.add("B");
set.add("A");
set.add("1");
set.add("2");
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next() + " ");
}
System.out.println();
}
}
O(N)
으로 좋지 않다.HashSet
은 데이터의 양이 배열 크기의 75%를 넘어가면 배열 크기를 2배로 늘리고 2배 늘어난 크기를 기준으로 모든 요소에 해시 인덱스를 다시 적용한다.HashSet
의 기본 크기는 16이다.