static void swap(int& first, int& second)
{
int temp = first;
first = second;
second = temp;
}
static void recursion(std::vector<int>& buf, int start, int end)
{
if (start >= end)
return;
int& pivot = buf[start];
int left = start + 1;
int right = end;
while (true)
{
while (left <= right && buf[left] <= pivot)
++left;
while (left <= right && buf[right] > pivot)
--right;
if (left > right)
break;
swap(buf[left], buf[right]);
}
swap(pivot, buf[right]);
recursion(buf, start, right - 1);
recursion(buf, right + 1, end);
}
호출한 재귀함수는 입력 버퍼와 start 인덱스, end 인덱스를 인자로 받는다.
그리고 피벗을 기준으로 요소들을 나누기 위해 중요한 과정을 진행한다.
우선 피벗 제외 버퍼의 맨 왼쪽 index를left, 맨 오른쪽 index를right로 지정한다.
left가 가리키는 요소가 피벗보다 클 때까지 left를 증가시킨다.
이후 right가 가리키는 요소가 피벗보다 작거나 같을 때까지 right를 감소시킨다.
이 때, left가 right를 지나쳤다면 반복문을 종료한다.
그렇지 않다면, left 값과 right 값을 바꾸고 반복문을 재개한다.
반복문이 종료되는 경우는 다음 두 가지다.
1. left 차례에 right를 지나쳤다면, right가 가리키고 있는 값은 피벗보다 작다는 뜻이고
2. right 차례에 left를 지나쳤다면, left가 지나쳐온 피벗보다 작은 값을 right가 가리키게 된다.
결국 right가 가리키는 값이 항상 피벗보다 작거나 같게 되므로 피벗과 right 값을 바꾼다면 해당 버퍼는 피벗의 왼쪽에는 피벗보다 작은 값이, 피벗의 오른쪽에는 피벗보다 큰 값이 위치하게 된다.
이제 피벗을 기준으로 양 옆 버퍼를 분할하여 각 재귀함수를 호출한다.
최악의 경우
피벗을 왼쪽에 두었을 때,
오름차순 혹은 내림차순으로 정렬되어있는 입력 버퍼의 경우O(N^2)의 시간복잡도를 보인다.