자료구조
자료구조 - 퀵 정렬
tita
2024. 6. 11. 13:56
[퀵 정렬(Quick Sort)]
퀵 정렬(Quick Sort)은 분할 정복(Divide and Conquer) 알고리즘의 하나로, 평균적으로 가장 빠른 정렬 알고리즘 중 하나입니다.
리스트를 분할하고 정복하며, 재귀적으로 정렬을 수행합니다.
퀵 정렬은 피벗(pivot)을 선택하여 리스트를 분할하고, 분할된 부분 리스트를 정렬합니다. 시간 복잡도는 평균적으로 이지만, 최악의 경우 O(n^2) 입니다.
퀵 정렬 과정
- 리스트에서 피벗을 선택합니다. 보통 리스트의 중간 요소를 선택합니다.
- 피벗을 기준으로 작은 요소는 피벗의 왼쪽으로, 큰 요소는 피벗의 오른쪽으로 분할합니다.
- 분할된 부분 리스트에 대해 재귀적으로 퀵 정렬을 수행합니다.
- 재귀적인 호출이 끝나면 모든 부분 리스트가 정렬되었으므로 리스트를 합병합니다.
퀵 정렬 의사 코드
함수 quickSort(arr, low, high):
if low < high:
// 리스트를 분할하고 피벗의 인덱스를 반환
pivot_idx = partition(arr, low, high)
// 피벗을 기준으로 왼쪽 부분 리스트 정렬
quickSort(arr, low, pivot_idx - 1)
// 피벗을 기준으로 오른쪽 부분 리스트 정렬
quickSort(arr, pivot_idx + 1, high)
함수 partition(arr, low, high):
pivot = arr[high] // 피벗을 선택
i = low - 1 // 작은 요소들의 끝을 나타내는 인덱스
for j = low부터 high-1까지:
if arr[j] <= pivot:
i += 1
arr[i]와 arr[j]를 교환
arr[i + 1]와 arr[high]를 교환 // 피벗을 올바른 위치로 이동
반환 i + 1 // 피벗의 인덱스 반환
퀵 정렬 예제
예시 리스트: [64, 25, 12, 22, 11]
첫 번째 재귀 호출:
리스트를 피벗을 기준으로 분할하여 피벗의 인덱스를 반환합니다.
피벗을 기준으로 왼쪽 부분 리스트([25, 12, 22, 11])와 오른쪽 부분 리스트([64])로 나뉩니다.
두 번째 재귀 호출(왼쪽 부분 리스트):
왼쪽 부분 리스트를 다시 분할하여 피벗의 인덱스를 반환합니다.
피벗을 기준으로 왼쪽 부분 리스트([12, 11])와 오른쪽 부분 리스트([25, 22])로 나뉩니다.
세 번째 재귀 호출(왼쪽 부분 리스트):
왼쪽 부분 리스트는 더 이상 분할할 수 없으므로 재귀 호출이 종료됩니다.
세 번째 재귀 호출(오른쪽 부분 리스트):
오른쪽 부분 리스트도 더 이상 분할할 수 없으므로 재귀 호출이 종료됩니다.
퀵 정렬 코드
#include <iostream>
#include <vector>
using namespace std;
// 리스트를 피벗을 기준으로 분할하고 피벗의 인덱스를 반환
int partition(vector<int>& arr, int low, int high)
{
int pivot = arr[high]; // 피벗 선택
int i = low; // 작은 요소들의 끝을 나타내는 인덱스
for (int j = low; j < high; j++)
{
if (arr[j] <= pivot)
{
swap(arr[i], arr[j]);
i++;
}
}
swap(arr[i], arr[high]); // 피벗을 올바른 위치로 이동
return i;
}
// 퀵 정렬 함수
void quickSort(vector<int>& arr, int low, int high)
{
if (low < high)
{
// 리스트를 분할하고 피벗의 인덱스를 반환
int pivot_idx = partition(arr, low, high);
// 피벗을 기준으로 왼쪽 부분 리스트 정렬
quickSort(arr, low, pivot_idx - 1);
// 피벗을 기준으로 오른쪽 부분 리스트 정렬
quickSort(arr, pivot_idx + 1, high);
}
}
int main()
{
vector<int> arr = {64, 25, 12, 22, 11}; // 예제 리스트
cout << "정렬 전: ";
for (int i : arr)
{
cout << i << " ";
}
cout << endl;
// 퀵 정렬 수행
quickSort(arr, 0, arr.size() - 1);
cout << "정렬 후: ";
for (int i : arr)
{
cout << i << " ";
}
cout << endl;
return 0;
}