Algorithm - (7) 퀵 소트
퀵 정렬 (Quick sort)
퀵!소트인만큼 시간복잡도가 낮다
- 데이터중에서 기준점(pivot 이라고 부름)을 정해서, 기준점보다 작은 데이터는 왼쪽(left), 큰 데이터는 오른쪽(right) 으로 모으는 함수를 작성함
- 각 왼쪽(left), 오른쪽(right)은 재귀용법을 사용해서 다시 동일 함수를 호출하여 위 작업을 반복함
- 함수는 왼쪽(left) + 기준점(pivot) + 오른쪽(right) 을 리턴함
- 핵심 - 피봇 이있고 피봇기준으로 왼쪽오른쪽으로 데이터를 나눈다
- 그리고 재귀적으로 위 작업을 수행한다.
- 피봇은 rule에 따라서 설정하는데 보통 맨 앞데이터, 맨 뒤 데이터를 피봇으로 설정
시간 복잡도
병합정렬과 유사, 시간복잡도는 O(n log n)
- 단, 최악의 경우
- 맨 처음 pivot이 가장 크거나, 가장 작으면
- 모든 데이터를 비교하는 상황이 나옴
- $O(n^2)$
Pseudocode for Python
- quicksort 함수 만들기
- 만약 리스트 갯수가 한개이면 해당 리스트 리턴
- 그렇지 않으면, 리스트 맨 앞의 데이터를 기준점(pivot)으로 놓기
- left, right 리스트 변수를 만들고,
- 맨 앞의 데이터를 뺀 나머지 데이터를 기준점과 비교(pivot)
- 기준점보다 작으면 left.append(해당 데이터)
- 기준점보다 크면 right.append(해당 데이터)
- return quicksort(left) + pivot + quicksort(right) 로 재귀 호출
리스트로 만들어서 리턴하기: return quick_sort(left) + [pivot] + quick_sort(right)
Python code implementation
- python solution (1)
def qsort(data):
if len(data) <= 1:
return data
left, right = list(), list()
pivot = data[0]
for index in range(1, len(data)):
if pivot > data[index]:
left.append(data[index])
else:
right.append(data[index])
return qsort(left) + [pivot] + qsort(right)
- python solution (2)
def qsort(data):
if len(data) <= 1:
return data
pivot = data[0]
left = [ item for item in data[1:] if pivot > item ]
right = [ item for item in data[1:] if pivot <= item ]
return qsort(left) + [pivot] + qsort(right)
import random
data_list = random.sample(range(100), 10)
qsort(data_list)
Analysis for C++ code
- 마지막 데이터를 피벗으로 선택
- 왼쪽(i)에서 오른쪽으로 가면서 피벗보다 작은 수 찾음
- 각 인덱스 i, j에 대한 요소를 교환
- 2,3번 과정 반복
- 더이상 2,3번 진행이 불가능하면, 현재 피벗과 교환
- 이제 교환된 피벗 기준으로 왼쪽엔 피벗보다 작은 값, 오른쪽엔 큰 값들만 존재함
C++ code implementation
#include<iostream>
using namespace std;
void swap(int* a, int* b);
int quickSplit(int* data, int low, int high)
{
int pivot = data[high]; //last element as pivot
int i = low; // Index of smaller element
for (int j = low; j < high; j++)
{
// If current element is smaller than the pivot
if (data[j] < pivot)
{
i++; // increment index of smaller element
swap(&data[i-1], &data[j]);
}
}
swap(&data[i], &data[high]);
return i;
}
void quickSort(int* data, int start, int end)
{
if(start >= end)
return;
//index means the pivot data's index of the result for quickSplit
int index = quickSplit(data, start, end);
quickSort(data, start, index-1);
quickSort(data, index+1, end);
}
int main()
{
int list_q[] = {5,3,1,8,7,4,9,2};
int len = sizeof(list_q) / sizeof(list_q[0]);
cout << len << endl;
quickSort(list_q, 0, len-1);
for(int i = 0; i < len; ++i)
cout << list_q[i] << " ";
return 0;
}
void swap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}