알고리즘 문제를 풀면서 sort() 메서드를 사용할 때, 정렬 방식과 시간 복잡도 차이가 있다는 것을 알게 되었다.
그래서 오늘은 Java에서 제공하는 sort() 메서드에 대해 정리해 보려고 한다.
📌 Java의 주요 정렬 메서드
자바에서 정렬을 수행할 때 주로 사용하는 정렬 메서드는 다음과 같다.
- Arrays.sort() → 배열 정렬
- Collections.sort() → 리스트 정렬
두 메서드는 내부적으로 다른 정렬 알고리즘을 사용하므로, 시간 복잡도와 안정성(Stable Sort 여부)이 다를 수 있다.
📌 정렬 방식과 시간 복잡도 비교
정렬 메서드 | 정렬 알고리즘 | 평균 시간 복잡도 | 최악 시간 복잡도 | 안정 정렬 여부 |
Arrays.sort() (기본 타입) |
Dual-Pivot QuickSort | O(n log n) | O(n²) (최악) | ❌ (비안정 정렬) |
Arrays.sort() (객체 배열) |
TimSort (Merge + Insertion) |
O(n log n) | O(n log n) | ⭕ (안정 정렬) |
Collections.sort() | TimSort (Merge + Insertion) |
O(n log n) | O(n log n) | ⭕ (안정 정렬) |
💡 안정 정렬(Stable Sort)이란 ?
동일한 값을 가진 요소가 정렬 후에도 기존 상대적 순서를 유지하는 정렬 방식을 말한다.
📌 각 정렬 방식의 특징
1️⃣ Arrays.sort()
- 기본 타입 배열 (int[], double[] 등) → Dual-Pivot QuickSort 사용
- 객체 배열(Integer[], String[] 등) → TimSort 사용
- 기본 타입 배열 정렬 시 비안정 정렬(unstable sort)
- 객체 배열 정렬 시 안정 정렬 (stable sort)
int[] arr = {5, 2, 9, 1, 5};
Arrays.sort(arr); // Dual-Pivot QuickSort 사용
2️⃣ Collections.sort()
- 내부적으로 List.sort()를 호출 → TimSort (합병 정렬 + 삽입 정렬) 사용
- List<T>에서 Comparable을 구현한 요소 정렬 가능
- 안정 정렬 (stable sort) 보장
List<Integer> list = Arrays.asList(5, 2, 9, 1, 5);
Collections.sort(list); // TimSort 사용
sort() 메서드의 차이를 확인해 보기 위해 백준 2751 수 정렬하기 2 문제를 예시로 들어보자.
처음에는 Arrays.sort()를 사용하여 정렬을 시도했다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = Integer.parseInt(br.readLine());
}
Arrays.sort(arr);
StringBuilder sb = new StringBuilder();
for (int num : arr) {
sb.append(num).append("\n");
}
System.out.println(sb.toString());
br.close();
}
}
이 방식은 Dual-Pivot QuickSort를 사용하여 평균 O(n log n)이지만, 최악의 경우 O(n²)로 인해 시간 초과가 발생할 수 있다.
이 문제를 Collections.sort()를 사용하여 해결하면 시간 초과를 피할 수 있다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i < n; i++) {
list.add(Integer.parseInt(br.readLine()));
}
Collections.sort(list);
StringBuilder sb = new StringBuilder();
for (int num : list) {
sb.append(num).append("\n");
}
System.out.println(sb.toString());
br.close();
}
}
Collections.sort(List<Integer>)는 TimSort를 사용하여 최악의 경우에도 O(n log n)을 보장하므로 훨씬 안정적인 정렬 성능을 제공한다.
'Java' 카테고리의 다른 글
[Java] equals(), hashCode() (0) | 2025.02.24 |
---|---|
[Java] static 변수, static 메서드 (0) | 2025.02.23 |
[Java] 자료형(Data Type), 형 변환 (0) | 2025.02.01 |
[Java] 정규 표현식(Regular Expression, Regex) (0) | 2025.01.30 |
[Java] 예외(Exception), 예외 처리(Exception Handling) (0) | 2025.01.20 |