티스토리 뷰
카운팅 정렬(Counting Sort)는 각 항목의 개수를 세어 저장해 두고, 그에 따라서 적절한 위치에 정렬하는 효율적인 알고리즘 입니다. 오름, 내림차순 정렬과정, 시간 복잡도, 특징등에 대해서 알아보겠습니다 !
카운팅 정렬이란?
정렬하고 싶은 배열 항목들의 순서를 결정하기 위해 각 항목(요소)들이 몇 개씩 있는지 세어서 적절한 위치에 정렬하는 방법입니다.
각 항목의 개수를 기록하기 위해 정수로 인덱스 되는 카운트 리스트를 사용하기 때문에 정수나 정수로 표현할 수 있는 자료에만 적용할 수 있는 알고리즘입니다.
예를 들어 배열 [1, 2, 3, 1, 5, 6]이 있다고 하면 1은 2개가 있고 나머지 원소들은 1개가 배열 내에 존재합니다. 그러므로 배열 내에서 가장 큰 수를 반드시 알아야합니다.
파이썬에는
1. 다른 리스트를 두고 인덱스로 기록하는 방법
2. 딕셔너리를 활용하여 Key-Value로 기록하는 방법
두 가지 방법으로 구현할 수 있습니다.
정렬 과정
Arr: 정렬할 데이터 배열
cnt_list: 카운팅 리스트 배열
answer: 정렬된 리스트 배열 (Arr 배열과 길이가 같은 배열)
1. 정렬할 데이터에서 각 항목들의 개수를 세고, 정수 항목들로 직접 인덱스 되는 카운트 리스트에 저장
> Arr [3, 1, 2, 1, 4, 5] / cnt_list [2, 1, 1, 1, 1]
0이 0개, 1이 2개, 2가 1개, 3이 1개, 4가 1개, 5가 1개 있다는 cnt_list 입니다.
2. 정렬된 집합에서 각 항목(요소)의 앞에 위치할 항목의 개수를 반영합니다.
즉 해당 요소 앞에 몇 개의 원소가 있는지 체크한다는 것입니다.
배열 요소들을 차례대로 더해주면 알 수 있습니다.
여기서 배열을 사용하지 않고 dict를 사용하여 구현할 수도 있습니다.
마찬가지로 key, value를 이용하여 체크해주면 됩니다.
> cnt_list [2, 3, 4, 5, 6] (오름차순)
> cnt_list [6, 4, 3, 2, 1] (내림차순) 내림차순은 역순으로 더해줍니다.
3. 데이터의 마지막 항목부터 원소를 정렬합니다.
오름차순을 예시로 들어보겠습니다.
Arr [3, 1, 2, 1, 4, 5]의 마지막 원소는 '5'입니다.
아래에서 말하는 인덱스는 cnt_list에서의 인덱스입니다. 배열에서 인덱스는 [해당숫자 - 1]로 표현합니다.
1) 마지막 원소는 5, 인덱스는 4입니다. cnt_list[5-1]의 값은 6입니다. answer의 6번째 위치에 5를 삽입하고 cnt_list값을 감소합니다.
answer = [0, 0, 0, 0, 0, 5]
2) 뒤에서 2번째 원소는 4, 인덱스는 3입니다. cnt_list[3]의 값은 5입니다. answer의 5번째 위치에 4를 삽입하고 cnt_list값을 감소합니다.
answer = [0, 0, 0, 0, 4, 5]
3) 뒤에서 3번째 원소는 1, 인덱스는 0입니다. cnt_list[0]의 값은 2입니다. answer의 2번째 위치에 1을 삽입하고 cnt_list값을 감소합니다.
answer = [0, 1, 0, 0, 4, 5]
4) 뒤에서 4번째 원소는 2, 인덱스는 1입니다. cnt_list[1]의 값은 3입니다. answer의 3번째 위치에 2를 삽입하고 cnt_list값을 감소합니다.
answer = [0, 1, 2, 0, 4, 5]
5) 뒤에서 5번째 원소는 1, 인덱스는 0입니다. 3번 과정에서 값을 감소하였기 때문에 cnt_list[0]의 값은 1입니다. answer의 1번째 위치에 1을 삽입하고 cnt_list값을 감소합니다.
answer = [1, 1, 2, 0, 4, 5]
6) 첫번째 원소는 3, 인덱스는 2입니다. cnt_list[2]의 값은 4입니다. answer의 4번째 위치에 3을 삽입하고 cnt_list값을 감소합니다.
answer = [1, 1, 2, 3, 4, 5]
오름차순으로 정렬이 완료된 answer 배열을 얻을 수 있습니다.
시간 복잡도와 특징
- n: 데이터 개수, k: 배열 내부에서 최대값
- 평균 수행시간: O(n+k)
- Bad Case: O(n+k)
- 즉 k의 값이 엄청나게 큰 경우에 엄청난 시간 손해가 발생한다.
- k값이 1억이 넘게되면 1초이상 걸리게 된다
- n >> k 인 경우에는 O(n)으로 해결할 수 있다
- 장점: 정렬하려는 수의 개수가 적을 때 빠르게 정렬할 수 있다.
- 단점: 추가적인 메모리 할당이 필요하고, 개수가 많아지면 성능이 굉장히 저하된다.
관련 문제: https://www.acmicpc.net/problem/10989
알고리즘을 코드로 구현한 자료는 구글링하면 굉장히 쉽게 얻을 수 있기 때문에 따로 작성하지 않겠습니다 !
'알고리즘' 카테고리의 다른 글
[백준] 2580 스도쿠 - 파이썬 (시간초과 풀이 및 해결) (0) | 2022.03.17 |
---|---|
[프로그래머스] 보석 쇼핑 - 파이썬 (0) | 2022.03.13 |
[프로그래머스] 다단계 칫솔 판매 - 파이썬 (0) | 2022.03.08 |
[프로그래머스] 124 나라의 숫자 - 파이썬 (0) | 2022.02.24 |
[프로그래머스] 기능개발 - 파이썬 (0) | 2022.02.24 |
- Total
- Today
- Yesterday
- 피움
- jpa
- ZNS SSD
- dm-zoned 코드분석
- 런칭 페스티벌
- 우테코 회고
- ZNS
- 파이썬
- 2차 데모데이
- dm-zoned
- 스프링 프레임워크
- 스프링 부트
- 팀프로젝트
- java
- 네트워크
- 회고
- 8주차 회고
- 알림개선기
- 알림기능개선기
- 3차 데모데이
- Spring
- 피움 6주차 회고
- 우테코
- 프로젝트
- 스프링 Logback
- 스프링MVC
- 백준
- CI/CD
- 환경 별 로깅 전략 분리
- 5주차 회고
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |