Lesson 내장 정렬의 개념과 언제 쓰는가
정렬이란
정렬(sorting) 은 원소들을 어떤 기준(대소, 사전순 등)에 따라 한 줄로
줄 세우는 것입니다. 거의 모든 알고리즘 풀이의 첫 줄이 되는 전처리로,
"정렬해 놓고 보면 규칙이 보이는" 경우가 압도적으로 많습니다.
직접 정렬 알고리즘을 짤 일은 실전에서 거의 없습니다. 언어가 제공하는
내장 정렬(C++ std::sort, Python sorted/list.sort)이 빠르고
검증돼 있기 때문입니다. 이 강의는 "정렬을 어떻게 짜느냐"가 아니라
"내장 정렬을 정확히 불러 쓰는 법" 을 다룹니다.
복잡도
내장 정렬은 비교 기반이며 시간 복잡도는 \(O(N \log N)\)입니다. \(N = 10^6\)
정도까지도 순식간에 처리됩니다. 비교 함수가 \(O(1)\)이 아니라 문자열 비교처럼
\(O(L)\)이면 전체는 \(O(N L \log N)\)이 되니 주의하세요.
- 원소 \(N\)개 정렬: \(O(N \log N)\)
- \(O(N^2)\) 정렬(버블·삽입 등)은 \(N\)이 커지면 시간 초과. 절대 직접 짜지 마세요.
언제 정렬을 떠올리는가
정렬은 그 자체가 목적이기보다 다른 기법의 전제 조건인 경우가 많습니다.
- 이분 탐색을 하려면 데이터가 정렬돼 있어야 합니다.
- 투 포인터 / 그리디의 상당수는 "정렬 후" 성립합니다.
- 중복 제거·최빈값·인접 원소 비교: 정렬하면 같은 값이 붙습니다.
- "\(K\)번째로 큰/작은 값", "차이가 가장 작은 두 수" 같은 질문.
막혔을 때 "이 데이터를 정렬하면 뭐가 보이지?"를 먼저 던져 보세요.
가장 단순한 예
배열을 오름차순으로 정렬하기.
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int> a = {5, 2, 9, 1, 5, 6};
sort(a.begin(), a.end()); // 1 2 5 5 6 9
}
a = [5, 2, 9, 1, 5, 6]
a.sort() # 제자리 정렬: [1, 2, 5, 5, 6, 9]
b = sorted(a) # 새 리스트를 반환 (원본 보존)
sort(제자리)와 sorted(새 리스트 반환)의 차이를 기억하세요. C++의
sort는 항상 제자리 정렬이며 반복자 구간 [begin, end) 를 받습니다.