C/C++ 알고리즘

C와 C++의 퀵 정렬(quick sort)

이 레슨에서는 피벗 요소를 기준으로 배열을 분할하는 퀵 정렬을 구현합니다.

소개

퀵 정렬은 요소 하나를 피벗으로 고른 다음, 피벗보다 작은 요소는 왼쪽에, 나머지는 오른쪽에 오도록 배열을 다시 배치합니다. 그러면 피벗은 최종 위치에 놓이고, 알고리즘은 양쪽을 재귀로 정렬합니다.

핵심 정리

  • 빈 입력, 요소 하나, 중복 값, 이미 정렬된 데이터로 테스트하세요.
  • 먼저 코드가 올바르게 동작하게 만든 다음 최적화하세요.
  • 실제 코드에서는 표준 라이브러리의 이미 만들어진 함수를 우선 쓰세요.

C와 C++의 퀵 정렬(quick sort) 시각화

O(n log n)

재생 또는 한 단계를 눌러 비교와 데이터 이동 과정을 확인하세요.

C와 C++ 코드 예제

C
실행 →
main.c
#include <stdio.h>

void swap(int *left, int *right) {
    int temporary = *left;
    *left = *right;
    *right = temporary;
}

int partition(int *values, int low, int high) {
    int pivot = values[high];
    int boundary = low;
    for (int scan = low; scan < high; ++scan) {
        if (values[scan] < pivot) {
            swap(&values[boundary++], &values[scan]);
        }
    }
    swap(&values[boundary], &values[high]);
    return boundary;
}

void quick_sort(int *values, int low, int high) {
    if (low >= high) return;
    int pivot = partition(values, low, high);
    quick_sort(values, low, pivot - 1);
    quick_sort(values, pivot + 1, high);
}

int main(void) {
    int values[] = {9, 4, 7, 3, 10, 5};
    quick_sort(values, 0, 5);
    for (int index = 0; index < 6; ++index) {
        printf("%d ", values[index]);
    }
}
실행 결과
3 4 5 7 9 10
C++
실행 →
main.cpp
#include <algorithm>
#include <iostream>
#include <vector>

template<class Iterator>
void quick_sort(Iterator first, Iterator last) {
    if (last - first < 2) return;
    auto pivot = *(last - 1);
    auto middle = std::partition(first, last - 1,
        [pivot](int value) { return value < pivot; });
    std::iter_swap(middle, last - 1);
    quick_sort(first, middle);
    quick_sort(middle + 1, last);
}

int main() {
    std::vector values{9, 4, 7, 3, 10, 5};
    quick_sort(values.begin(), values.end());
    for (int value : values) {
        std::cout << value << ' ';
    }
}
실행 결과
3 4 5 7 9 10

C와 C++ 비교

C의 partition 함수는 마지막 요소를 피벗으로 고르고, 변수 boundary로 작은 요소 구간의 경계를 표시합니다. 마지막에 피벗을 boundary 위치와 맞바꿉니다. C++ 버전은 std::partition으로 분할을 더 짧게 표현합니다. 평균 복잡도는 O(n log n)이지만 피벗을 잘못 고르면 O(n²)까지 늘어날 수 있습니다.

C

반복문, 포인터, 길이, 임시 버퍼를 모두 명시적으로 작성합니다.

C++

반복자와 표준 알고리즘이 처리 방식과 데이터를 저장하는 방식을 분리합니다.

연습 문제

두 버전을 모두 실행한 다음 코드를 바꿔 보면서 각 언어가 주는 안전성의 차이를 살펴보세요.

  • 종이에 비교 과정을 하나씩 따라가 보세요.
  • 중복 값과 아주 크거나 작은 값으로 테스트해 보세요.
  • 직접 작성한 코드의 실행 시간을 재고 표준 라이브러리와 비교해 보세요.

챌린지로 연습하기

이 레슨에서 배운 내용으로 실제 문제를 풀어 보세요. 모든 챌린지는 브라우저에서 실행되며 즉시 테스트와 AI 리뷰를 받을 수 있습니다.

모든 챌린지