알고리즘 목적
기준값(pivot, 피벗)을 기준으로 배열을 분할하는 알고리즘이다. 배열을 피벗보다 낮은 영역과 피벗보다 큰 영역으로 나눈다. 영역을 나눈 후에 피벗을 자기 자리에 배치한다.
기준값을 기준으로 배열을 분할한다고 해서 반드시 정렬되어야 하는 것은 아니다.
시간복잡도는 Θ(N)이다.
알고리즘 구현
동작과정
- pivot을 정한다
- pivot보다 작은 값을 발견할 경우, 왼쪽 영역을 확장하고 자리를 교체한다.
- 모든 데이터를 순회했으면 pivot을 배치한다.
구현
#include <iostream>
#include <vector>
using namespace std;
void Print(vector<int> &arr) {
for (int i = 0; i < arr.size(); i++)
cout << arr[i] << " ";
cout << endl;
}
int main() {
vector<int> arr = {5, 2, 7, 3, 8, 5, 6, 4};
// vector<int> arr = { 2, 8, 7, 1, 3, 5, 6, 4 };
// vector<int> arr = { 9, 8, 7, 6, 4, 3, 2, 1, 5 };
// vector<int> arr = { 5, 2, 7, 3, 4, 4, 6, 4 };
int lo = 0; // 첫 인덱스
int hi = arr.size() - 1; // 마지막 인덱스
int x = arr[hi]; // 분할 기준으로 사용하는 pivot 4
int i = lo - 1; // pivot보다 것들중 가장 큰 인덱스
Print(arr);
// COMPLETE:
// NOTE: 배열의 영역을 나누기 위해 작은 값을 담당하는 영역의 포인터와 큰 값을 담당하는 영역와 배열 전체를 순회하는
// 포인터를 사용
for (int j = lo; j < hi; j++) {
if (arr[j] < x) {
swap(arr[++i], arr[j]);
}
}
swap(arr[i + 1], arr[hi]);
Print(arr);
cout << i + 1 << endl; // 피벗 이하인 값들의 마지막 인덱스
}