카운팅 정렬(Counting Sort)
- 카운팅 정렬은 계수 정렬이라고도 한다.
- 카운팅 정렬은 정수로 이루어진 리스트만 정렬이 가능하다. 리스트의 정수의 값을 인덱스로 활용하는 방법을 사용하기 때문이다.
- 그러므로, 값이 인덱스가 되기 위해서는 리스트 안의 최대값을 알아야 그 크기에 맞는 새로운 리스트를 선언해 줄 수 있다.
- 0~100점 사이인 학생들의 성적과 같이 중복되는 값이 발생하는 리스트의 정렬에 좋음. 만약 값 차이가 많이나서 값이 0 ~ 100000 사이인 배열이라면 공간을 많이 차지할 수 있다.

사실 이해하기 처음엔 매우 어려울 수 있다. 과정은 다음과 같다.
- 배열 안의 가장 큰 수만큼의 크기의 리스트 c를 생성 후 0을 전부 할당.
- 순서대로 초기 입력받은 리스트 arr에 있는 중복된 수의 개수만큼 arr의 값에 해당하는 인덱스에 할당.
ex) arr[1] = 9 arr[10] = 9 였으면 9가 두 번 나왔으므로, c[9] = 2가 되는 것이다.
- 리스트 c 값들의 누적합을 저장해가며 구한다.
- arr와 같은 크기의 sorted_arr를 생성해 arr에서 순서대로 나온 값들이 c의 인덱스 값이 되고, c의 인덱스 안의 값 -1 은 새로운 sorted_arr의 인덱스가 된다. 그리고 중복된 값이 arr에 있을 수 있으니 호출된 c의 인덱스를 1씩 감소시켜 줘야만 중복 값도 출력이 된다.
def counting_sorted(arr, K):
c = [0] * K
sorted_arr = [0] * len(arr)
for i in arr:
c[i] += 1
for i in range(1,K):
c[i] += c[i-1]
for i in range(len(arr)):
sorted_arr[c[arr[i]]-1] = arr[i]
c[arr[i]] -= 1
return sorted_arr
arr = [3, 5, 1, 2, 9, 6, 4, 7, 5, 1, 1, 1]
print(counting_sorted(arr, 20))
*시간복잡도는 선형 시간으로 O(N+k)이다. k는 배열에 있는 수의 최대값을 의미한다.
*효율이 좋지만 정수나 정수로 표현되는 값들을 가져야만 쓸 수 있고, 리스트의 크기가 작은데 값들의 차이가 심한 경우에는 공간 효율이 안좋다.