퀵 정렬은 임의의 원소를 피벗으로 하여, 피벗과 비교하여 작은 값이 모인 집합과 큰 값이 모인 집합 두개로 나눕니다. 그 후 만들어진 두 집합 역시 동일한 과정을 거쳐 원소를 하나만 가질때까지 반복합니다. 퀵 정렬은 최악의 경우 의 시간 복잡도를 가지게 되는 데, 그럼에도 병합정렬이 아닌 퀵 정렬을 사용하는 이유는 평균 시간 복잡도는 으로 병합 정렬보다 빠르기 때문입니다. 또한 추가적인 메모리를 필요로하지 않고, 입력 배열 자체를 정렬하는 제자리 정렬 알고리즘입니다.

다음은 퀵 정렬의 코드입니다.

#include <iostream>
#include <vector>
using namespace std;
 
template<typename T>
auto partition(typename vector<T>::iterator begin, typename vector<T>::iterator end)
{
    auto pivot_val=*begin;
    auto left_iter=begin+1;
    auto right_iter=end;
    while (true)
    {
        while (*left_iter<=pivot_val&&std::distance(left_iter, right_iter)>0)
           left_iter++;
        while (*right_iter>pivot_val&&std::distance(left_iter, right_iter)>0)
           right_iter--;
        if(right_iter==left_iter)
            break;
        else
            iter_swap(left_iter, right_iter);
        
    }
    if(pivot_val>*right_iter)
        iter_swap(begin, right_iter);
 
    return right_iter;
}
 
template<typename T>
void quick_sort(typename vector<T>::iterator begin, typename vector<T>::iterator end)
{
    if(distance(begin, end)>=1)
    {
        auto partition_iter = partition<T>(begin, end);
        quick_sort<T>(begin, partition_iter-1);
        quick_sort<T>(partition_iter,end);
    }
}
 
template<typename T>
void print_vector(vector<T> arr)
{
	for (auto i : arr)
		cout << i << " ";
	cout << endl;
}
 
void run_quick_sort_test()
{
	vector<int>	S1{ 45, 1, 3, 1, 2, 3, 45, 5, 1, 2, 44, 5, 7 };
	vector<float>	S2{ 45.6f, 1.0f, 3.8f, 1.01f, 2.2f, 3.9f, 45.3f, 5.5f, 1.0f, 2.0f, 44.0f, 5.0f, 7.0f };
	vector<double>	S3{ 45.6, 1.0, 3.8, 1.01, 2.2, 3.9, 45.3, 5.5, 1.0, 2.0, 44.0, 5.0, 7.0 };
	vector<char>	S4{ 'b', 'z', 'a', 'e', 'f', 't', 'q', 'u', 'y'};
 
	cout << "정렬되지 않은 입력 벡터:" << endl;
	print_vector<int>(S1);
	print_vector<float>(S2);
	print_vector<double>(S3);
	print_vector<char>(S4);
	cout << endl;
 
	quick_sort<int>(S1.begin(),S1.end()-1);
	quick_sort<float>(S2.begin(),S2.end()-1);
	quick_sort<double>(S3.begin(),S3.end()-1);
	quick_sort<char>(S4.begin(),S4.end()-1);
 
	cout << "퀵 정합에 의해 정렬된 벡터:" << endl;
	print_vector<int>(S1);
	print_vector<float>(S2);
	print_vector<double>(S3);
	print_vector<char>(S4);
	cout << endl;
}
 
int main()
{
	run_quick_sort_test();
	return 0;
}

각각의 함수에 대한 간단한 설명을 하겠습니다.
1. auto partition(typename vector<T>::iterator begin, typename vector<T>::iterator end)
해당 함수는 전달인자로 배열의 시작 주소와 마지막 주소를 받습니다. 그 후 첫 번째 주소에 저장된 원소를 피벗으로 두고, 피벗을 기준으로 작은 값은 왼쪽, 큰 값은 오른쪽에 배치하고 반환 값으로는 피벗보다 큰 원소의 주소를 반환합니다.

2. void quick_sort(typename vector<T>::iterator begin, typename vector<T>::iterator end)
해당 함수는 partition함수를 사용하여 얻은 원소를 기준으로 배열을 두개로 나누는 과정을 배열의 원소가 하나가 될 때까지 반복합니다.

이해를 돕기 위해 예시를 보겠습니다.

4513123455124457

퀵 정렬은 임의의 원소값을 기준으로 나누지만 해당 코드에서는 첫 번째 원소를 기준으로 배열을 분리 했기에 그를 따르도록 하겠습니다.(피벗은 파랑색)

13123455124457/45

1/11/32345524457/45

1/ 1/1/232 3/4554457/45

1/1/1/2 2/ 33/54457/45/45

1/1/1/2/2/3/3/55/457/45/45

1/1/1/2/2/3/3/5/5/7/45/45/45



위에서 보듯 운이 좋지않다면, 단 하나의 값만을 정렬하는 좋지 못한 모습도 보인다.
이 경우(최악의 경우)에는 시간복잡도는 이 될 것입니다.

알고리즘최선의 경우평균최악의 경우
병합 정렬
퀵 정렬