[알고리즘] 정렬(4) - 계수 정렬(Counting Sort)
2020. 4. 8. 23:59ㆍ알고리즘/이론
원리
1. 집합의 최댓값을 구해서 최대값만큼의 메모리를 차지하는 카운팅 배열을 만든다.
2. 각원소의 개수를 카운팅시킨다
3. 카운팅 배열의 누적합을 구한다.
4. 카운팅 배열을 통해 순서대로 수를 나열한다.
[ 15, 13, 10, 7, 5, 5, 1, 0, 7 ]
카운팅 배열에는 다음과 같이 구성될 수 있습니다.
Index | 0 | 1 | 5 | 7 | 10 | 13 | 15 |
count | 1 | 1 | 2 | 2 | 1 | 1 | 1 |
다음을 누적합의 표입니다.
Index | 0 | 1 | 5 | 7 | 10 | 13 | 15 |
count | 1 | 2 | 4 | 6 | 7 | 8 | 9 |
이때, 누적합을 구하는 이유는 어느 인덱스에 원본 원소가 들어갈지 순서를 강제하기 위해서 입니다.
정렬된 원소들이 들어갈 배열의 인덱스를 카운팅배열의 데이터 - 1로 설정 해줌으로서 정렬 해줄 수 있습니다.
예를들어, 연속된 수를 카운팅 정렬할때는 그저 누적합의 과정이 필요없이 나열하면 되지만, 만약 1,2,3,10000 이라는 수열 을 정렬한다고 한다면 (이미 정렬되어 있지만) 카운팅 배열을 10000까지 순회해야한다는 점 때문에 누적합 과정이 필요합니다.
그만큼 카운팅 정렬은 원소의 최댓값만큼의 용량을 가진 배열이 필요하고, 정수만을 정렬 할 수 있다는 단점이 있습니다.
구현
#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 20;
vector<int> CountingSort(const vector<int>& data)
{
int sz = data.size(); // 원본 배열의 사이즈
int mx = -0x07fffffff;
for (int d : data)
mx = max(d, mx); // 배열의 최댓값
vector<int> cnt(mx + 1, 0); // 카운팅 배열
/* 원소의 수만큼 카운트 */
for (int i = 0; i < sz; ++i)
cnt[data[i]]++;
/* 누적합 구하기 */
for (int i = 1; i < mx + 1; ++i)
cnt[i] = cnt[i - 1] + cnt[i];
vector<int> answer(sz); // 결과를 저장할 배열
/* 정렬 하기 */
for (int i = sz - 1; i >= 0; --i)
answer[--cnt[data[i]]] = data[i];
return answer;
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0);
clock_t s, e;
vector<int> arr(MAX_N);
srand((unsigned int)time(NULL));
for (int t = 0; t < 5; ++t)
{
for (int i = 0; i < MAX_N; ++i)
arr[i] = rand() % MAX_N;
s = clock();
arr = CountingSort(arr);
e = clock();
cout << (double)(e - s) / CLOCKS_PER_SEC << '\n';
}
}
시간복잡도
카운팅 정렬은 최대값 구하기, 누적합 구하기, 정렬하기 총 3번의 반복을 하기때문에 시간복잡도는 O(n)로 빠릅니다. 적절하게 사용한다면 효율이 굉장히 좋을것입니다.
정리
이름 | BEST | AVG | WORST | RUN TIME(정수 60,000) |
버블 정렬 | n^2 | n^2 | n^2 | 확인 |
선택 정렬 | n^2 | n^2 | n^2 | 확인 |
삽입 정렬 | n | n^2 | n^2 | 확인 |
계수 정렬 | n | n | n | 사진 참고 |
당연히 약 0ms의 런타임이 측정되었습니다.
실행 환경 :
- windows 10 WSL2 - ubuntu 18.04
- gcc 7.4.0
- cpu : i3
참조
-
'알고리즘 > 이론' 카테고리의 다른 글
[알고리즘] 정렬(5) - 병합 정렬(Merge Sort) (0) | 2020.04.09 |
---|---|
[알고리즘] 그래프(3) - 최소신장트리 MST (1) (0) | 2020.04.09 |
[알고리즘] 정렬(3) - 삽입 정렬(Insertion Sort) (0) | 2020.04.07 |
[알고리즘] 정렬(2) - 선택 정렬(Selection Sort) (0) | 2020.04.06 |
[알고리즘] 정렬(1) - 버블 정렬 (Bubble Sort) (0) | 2020.04.02 |