개념

인접한 두 요소를 비교하여 큰 값을 뒤로 보내는 정렬

가장 큰 값이 거품처럼 뒤로 올라가는 모습


시간복잡도

케이스시간복잡도
최선O(n)
평균O(n²)
최악O(n²)
공간복잡도O(1)

특징

장점

  • 구현 간단: 가장 이해하기 쉬운 정렬
  • 안정 정렬: 같은 값의 순서 유지
  • 제자리 정렬: 추가 메모리 불필요

단점

  • 매우 느림: O(n²) 시간복잡도
  • 비효율적: 실전에서 거의 사용 안 함

구현 방법

기본 구현

def bubble_sort(arr):
    n = len(arr)
 
    for i in range(n):
        # 마지막 i개는 이미 정렬됨
        for j in range(n - i - 1):
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
 
    return arr
 
# 테스트
print(bubble_sort([64, 34, 25, 12, 22, 11, 90]))
# [11, 12, 22, 25, 34, 64, 90]

최적화 버전 (조기 종료)

def bubble_sort_optimized(arr):
    n = len(arr)
 
    for i in range(n):
        swapped = False
 
        for j in range(n - i - 1):
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
                swapped = True
 
        # 교환이 없으면 이미 정렬됨
        if not swapped:
            break
 
    return arr
 
# 이미 정렬된 경우 O(n)

동작 과정

초기: [5, 3, 8, 4, 2]

1회전:
[3, 5, 8, 4, 2]  (5, 3 교환)
[3, 5, 8, 4, 2]  (5, 8 비교)
[3, 5, 4, 8, 2]  (8, 4 교환)
[3, 5, 4, 2, 8]  (8, 2 교환) → 8 확정

2회전:
[3, 5, 4, 2, 8]
[3, 4, 5, 2, 8]  (5, 4 교환)
[3, 4, 2, 5, 8]  (5, 2 교환) → 5 확정

3회전:
[3, 4, 2, 5, 8]
[3, 2, 4, 5, 8]  (4, 2 교환) → 4 확정

4회전:
[2, 3, 4, 5, 8]  (3, 2 교환) → 3 확정

완료: [2, 3, 4, 5, 8]

템플릿

def bubble_sort_template(arr):
    n = len(arr)
 
    # i: 확정된 요소 개수
    for i in range(n):
        swapped = False
 
        # j: 비교할 인덱스
        for j in range(n - i - 1):
            # 조건에 맞게 교환
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
                swapped = True
 
        # 최적화: 조기 종료
        if not swapped:
            break
 
    return arr

핵심 요약

개념설명
원리인접 요소 비교 및 교환
시간복잡도O(n²) - 최선 O(n)
공간복잡도O(1)
안정성안정 정렬

다른 정렬과 비교

정렬시간복잡도 (평균)공간복잡도안정성
버블 정렬O(n²)O(1)안정
선택 정렬O(n²)O(1)불안정
삽입 정렬O(n²)O(1)안정
병합 정렬O(n log n)O(n)안정
퀵 정렬O(n log n)O(log n)불안정

주의사항

1. 사용 시기

# 사용하지 않는 것이 좋음
# 교육용 또는 매우 작은 데이터(n < 10)에만

2. 대안

# Python 내장 정렬 사용 (Timsort)
arr.sort()  # O(n log n)
sorted(arr)

3. 최적화의 한계

# 최적화해도 O(n²)
# 거의 정렬된 경우만 O(n)

연습 문제

기초


언제 사용할까?

사용 가능

  • 데이터가 매우 적을 때 (n < 10)
  • 교육 목적
  • 이미 거의 정렬된 경우

사용 불가

  • 실전 프로그래밍
  • 대용량 데이터
  • 성능이 중요한 경우

결론: 실전에서는 사용하지 말 것!