일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- vim-go
- 알고리즘
- 연결리스트
- c++ heap
- OS
- JUCE 튜토리얼
- tour of go
- Docker
- 백준
- C++ gui 라이브러리
- 공룡책
- Nebula
- LOB
- 운영체제
- JUCE library
- gui
- JUCE
- go channel
- C++ library
- JUCE라이브러리
- 코딩
- C++ gui
- C언어
- 리듬게임
- 프로그래밍
- C++
- 자료구조
- go
- BOJ
- a tour of go
Archives
- Today
- Total
CafeM0ca
[알고리즘] quick sort 본문
반응형
시간복잡도
최선: NlogN (피벗이 중앙에 위치할 경우)
평균: NlogN
최악: N^2 (분할이 0:10으로 되는 경우)
소스코드
#include <iostream>
#include <random>
using namespace std;
void generate(vector<int>& v) {
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<> dis(1,30);
for(int i = 0; i < 10; i++) {
v.push_back(dis(gen));
}
}
int partition(vector<int>& v, int p, int r) {
int i = p-1, j = p;
while(j < r){
if(v[j] > v[r]) { // 오름차순
j++;
}
else {
i++;
swap(v[i], v[j]);
j++;
}
}
swap(v[r], v[i+1]);
return i+1;
}
void quicksort(vector<int>& v, int p, int r) {
if(p < r) {
// q = pivot pos
// 정렬
int q = partition(v, p, r);
// 작은쪽 분할
quicksort(v, p, q-1);
// 큰쪽 분할
quicksort(v, q+1, r);
}
}
int main() {
vector<int> v;
for(int i = 0; i < 10; i++) {
v.clear();
generate(v);
cout << "---before---\n";
for(auto& _v : v) {
cout << _v << " ";
}
cout << endl << endl;
quicksort(v, 0, v.size()-1);
cout << "---after---\n";
for(auto& _v : v) {
cout << _v << " ";
}
cout << "\n====================\n";
}
return 0;
}
피벗
위 소스코드에서는 피벗을 맨 마지막 원소로 선택하였다.
하지만 이는 좋은 방법이 아니다.
듀얼 피벗이나, 3개의 피벗을 선택하여 중앙값을 피벗으로 선택하는 방법이 있다.
아래 문제는 위의 소스코드를 활용하여 풀었을 때, 시간초과가 발생한다. 최악의 경우 N^2의 시간복잡도를 보이기 때문이다.
수 정렬하기4
하지만, 피벗을 랜덤으로 정하면 최악의 경우를 피할 수 있으므로 위 문제를 해결할 수 있다.
반응형
'Programming > 자료구조|알고리즘' 카테고리의 다른 글
[자료구조] priority queue 우선순위 큐 (0) | 2020.01.11 |
---|---|
[자료구조/알고리즘] heap과 heap sort (0) | 2020.01.02 |
[자료구조]Deque(C++ std::list) (0) | 2018.06.08 |
[알고리즘]선택정렬(C++) (0) | 2018.06.02 |
[자료구조]단일연결리스트(C 반복문) (0) | 2018.05.16 |
Comments