본문 바로가기
공부/알고리즘

계수 정렬(Counting Sort)

by 맑은청이 2020. 6. 1.
728x90
반응형

이때까지 배운 O(N log N)의 시간복잡도인 선택, 버블, 삽입 정렬 그리고 O(N^2)의 시간복잡도인 퀵, 병합, 힙 정렬을 배웠습니다. 가장 빨랐던 정렬은 아무래도 퀵정렬이었는데요. 이거보다 빠르게 정렬을 하는 계수 정렬에 대해 알아보겠습니다. 

 

다음의 5 이하 자연수 데이터들을 오름차순 정렬하세요.

 

1 3 5 2 3 1 3 4 4 3 4 2 3 4 3 1 1 2 4 3 3 1 2  3 4  5 1 3 2 4

 

정렬할 데이터 개수가 30개입니다. 특징은 모든 데이터가 1부터 5 사이입니다. 계수 정렬은 이처럼 적절한 '범위 조건'이 있어야한다는 전제에서 굉장히 빠른 알고리즘입니다. 그 속도는 O(N) 입니다. ( 저도 처음보는 시간복잡도의 속도입니다.) 

 

계수 정렬(Counting Sort)는 단순하게 '크기를 기준으로' 세는 알고리즘입니다.

 

무슨 말이냐면 이 알고리즘은 '크기를 기준으로' 인덱스별로 수를 세어주면 되기 때문에 배열 위치의 교환이 필요가 없습니다. 또한 모든 데이터에 한번씩만 접근하면(O(N) 이 되는 이유) 되기 때문에 굉장히 효율적입니다.

 

0. 초기상태

1 3 5 2 3 1 3 4 4 3 4 2 3 4 3 1 1 2 4 3 3 1 2  3 4  5 1 3 2 4

 

1 2 3 4 5
0 0 0 0 0

 

1. 1번째 

1 3 5 2 3 1 3 4 4 3 4 2 3 4 3 1 1 2 4 3 3 1 2  3 4  5 1 3 2 4

1 2 3 4 5
1 0 0 0 0

 

2. 2번째

1 3 5 2 3 1 3 4 4 3 4 2 3 4 3 1 1 2 4 3 3 1 2  3 4  5 1 3 2 4

1 2 3 4 5
1 0 1 0 0

3. 3번째

1 3 5 2 3 1 3 4 4 3 4 2 3 4 3 1 1 2 4 3 3 1 2  3 4  5 1 3 2 4

1 2 3 4 5
1 0 1 0 1

이런 식으로 쭉 해당 크기의 원소를 만ㄷ나는 경우 개수를 하나씩 올려주면 됩니다. 다음과 같은 방식으로 끝까지 진행을 하게 되면 결과는 다음과 같습니다. 

 

 

1 3 5 2 3 1 3 4 4 3 4 2 3 4 3 1 1 2 4 3 3 1 2  3 4  5 1 3 2 4

1 2 3 4 5
6 5 10 7 2

 

이제 해당 크기 1부터 5까지 나온 횟수만큼 출력을 해주면 됩니다. 1은 6번, 2는 5번, 3은 10번, 4는 7번, 5는 2번 출력을 해주면 되는 거죠.

 

1 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 5 5 

 

이렇게 출력이 됩니다. 

 

범위 조건이 충족이 될때 쓰기 좋은 알고리즘 코드 입니다. 물론 갑자기 크기가 10000 인 원소가 하나있다면 count의 인덱스가 count[100001] 이런식이 돼서 메모리 낭비가 심해지기 때문에 활용도가 높은 알고리즘이라고 할 수는 없습니다. 

 

 

728x90
반응형

'공부 > 알고리즘' 카테고리의 다른 글

너비 우선 탐색(BFS)  (0) 2020.06.03
알고리즘 스택, 큐  (0) 2020.06.03
힙정렬  (0) 2020.06.01
C++ Sort() 사용  (0) 2020.05.30
병합정렬 복습  (0) 2020.05.29