Foundry
자료구조
중급
핵심

정렬 알고리즘 비교

버블, 선택, 삽입, 퀵, 병합 정렬 비교

정렬 알고리즘 비교

데이터를 순서대로 배치하는 알고리즘. 상황에 따라 최적의 알고리즘이 다르다.

한눈에 비교

알고리즘평균최악공간안정
버블O(N²)O(N²)O(1)안정
선택O(N²)O(N²)O(1)불안정
삽입O(N²)O(N²)O(1)안정
병합O(N log N)O(N log N)O(N)안정
O(N log N)O(N²)O(log N)불안정
O(N log N)O(N log N)O(1)불안정

동작 원리

[버블 정렬] 인접 요소 교환
5 3 8 1 → 3 5 1 8 → 3 1 5 8 → 1 3 5 8

[선택 정렬] 최솟값을 앞으로
5 3 8 1 → 1|3 8 5 → 1 3|8 5 → 1 3 5 8

[삽입 정렬] 적절한 위치에 삽입
5|3 8 1 → 3 5|8 1 → 3 5 8|1 → 1 3 5 8

[병합 정렬] 분할 후 병합
5 3 8 1 → [5,3] [8,1]
→ [3,5] [1,8] → [1,3,5,8]

[퀵 정렬] 피벗 기준 분할
5 3 8 1 (피벗=5)
→ [3,1] 5 [8] → [1,3] 5 [8]

언제 무엇을 쓸까?

상황추천이유
거의 정렬됨삽입 정렬최선 O(N)
데이터 작음 (N<50)삽입 정렬오버헤드 적음
일반적인 경우퀵 정렬평균 가장 빠름
안정성 필요병합 정렬안정 + O(N log N)
메모리 제한힙 정렬O(1) 추가 공간
외부 정렬병합 정렬순차 접근

안정 정렬이란?

입력: (3,A) (1,B) (3,C) (2,D)

안정: (1,B) (2,D) (3,A) (3,C)
  → 같은 키(3)의 원래 순서 유지

불안정: (1,B) (2,D) (3,C) (3,A)
  → 같은 키의 순서가 바뀔 수 있음

실무에서의 정렬

언어/DB알고리즘
Python sort()Timsort (병합+삽입)
Java Arrays.sort()Dual-Pivot QuickSort
JavaScript sort()Timsort (V8)
PostgreSQL외부 병합 정렬

Timsort: 실제 데이터의 "거의 정렬된 부분"을 활용하여 삽입 정렬 + 병합 정렬을 결합한 하이브리드.

면접에서 이렇게 나옵니다

Q.퀵 정렬의 동작 원리와 최악의 경우를 설명해주세요.

기준값 하나를 골라 그보다 작은 것과 큰 것으로 나누고, 각 부분을 같은 방식으로 정렬합니다.

1. 기준값(피벗)을 하나 고른다
2. 작은 것은 왼쪽, 큰 것은 오른쪽으로 옮긴다
3. 기준값은 제자리에 확정된다
4. 왼쪽과 오른쪽에 같은 일을 반복한다
경우복잡도조건
최선과 평균O(n log n)기준값이 대체로 가운데를 나눈다
최악O(n의 제곱)기준값이 매번 최소나 최대

최악은 이미 정렬된 입력에 첫 원소를 기준값으로 쓸 때 나옵니다. 나누기가 1대 n-1로 되어 깊이가 n이 됩니다. 실무 데이터는 정렬돼 있는 경우가 흔해서 그냥 두면 최악을 자주 만납니다.

그래서 기준값을 무작위로 고르거나, 처음과 중간과 끝의 중간값을 씁니다.

흔한 실수: 최악이 O(n의 제곱)이라 병합 정렬보다 나쁘다고 답하는 것. 상수가 작고 제자리에서 정렬해 캐시 효율이 좋아, 실제로는 평균에서 가장 빠른 편입니다.

Q.병합 정렬과 퀵 정렬의 차이를 비교해주세요.

나누는 기준과 추가 메모리에서 갈립니다.

항목병합 정렬퀵 정렬
나누기항상 절반기준값에 따라 다르다
최악O(n log n)O(n의 제곱)
추가 메모리O(n)O(log n) 재귀 깊이
안정성안정불안정
실제 속도대체로 퀵보다 느리다평균에서 빠르다

병합 정렬은 절반씩 나누므로 최악이 없지만 합칠 때 별도 배열이 필요합니다. 퀵 정렬은 제자리에서 자리를 바꿔 메모리를 아끼고 캐시에 잘 맞습니다.

그래서 언어 표준 라이브러리는 이렇게 갈립니다.

대상표준 라이브러리가 쓰는 것
원시 타입 정렬퀵 정렬 계열. 순서가 바뀌어도 구분할 수 없다
객체 정렬병합 정렬 계열. 같은 키의 순서 유지가 필요하다

흔한 실수: 병합 정렬을 항상 피하는 것. 안정성이 필요하거나 최악을 보장해야 하는 곳(외부 정렬, 연결 리스트 정렬)에서는 병합 정렬이 정답입니다.

Q.안정 정렬이란 무엇이고 왜 중요한가요?

같은 키를 가진 원소들의 원래 순서가 유지되는 정렬입니다.

입력이 (김, 90), (이, 90), (박, 85) 이고 점수로 정렬한다고 해봅시다.

정렬결과같은 점수의 순서
안정(박, 85), (김, 90), (이, 90)김과 이가 그대로
불안정(박, 85), (이, 90), (김, 90)바뀔 수 있다

왜 중요한가는 두 번 정렬할 때 드러납니다.

1. 이름으로 정렬한다
2. 부서로 정렬한다
안정 정렬이면 같은 부서 안에서 이름순이 유지된다

불안정 정렬로 하면 1번의 결과가 흐트러져 두 기준을 함께 적용할 수 없습니다. 표의 열 머리글을 눌러 다중 정렬하는 화면이 이 성질에 의존합니다.

안정불안정
삽입, 병합, 버블퀵, 힙, 선택

흔한 실수: 값이 같으면 순서가 무의미하다고 답하는 것. 정렬 키가 아닌 다른 필드는 다르므로 사용자에게는 보이는 차이입니다.

Q.O(N²) 정렬과 O(N log N) 정렬의 차이를 설명해주세요.

비교 방식이 다릅니다. 앞은 모든 짝을 훑고, 뒤는 나누어 정복합니다.

구분대표아이디어
O(n의 제곱)버블, 선택, 삽입한 원소를 나머지와 비교해 자리를 찾는다
O(n log n)병합, 퀵, 힙절반씩 나누거나 힙 성질을 쓴다

규모에 따른 실제 격차입니다.

원소 수O(n의 제곱)O(n log n)
1,000100만약 1만
10만100억약 170만

초당 1억 번 연산으로 보면 10만 건에서 앞은 100초, 뒤는 0.02초입니다.

흔한 실수: 작은 입력에도 O(n log n)을 고집하는 것. 원소가 수십 개 이하면 상수가 작은 삽입 정렬이 더 빠릅니다. 실제 표준 라이브러리도 작은 구간은 삽입 정렬로 처리하는 혼합 방식을 씁니다. 그리고 삽입 정렬은 거의 정렬된 입력에서 O(n)이라 특정 상황에서는 최선입니다.

먼저 스스로 답해보고 아래 답변과 견줘보세요. 막히는 부분은 문제로 확인할 수 있어요.

읽었으면 문제로 확인해보세요

자료구조 문제를 풀면 틀린 문제가 자동으로 노트에 쌓입니다. 가입 없이 5문제를 먼저 풀어볼 수도 있어요.