본문 바로가기
알고리즘/개념

Counting Sort (계수 정렬)

by 도쿠니 2022. 4. 30.

 

 

출처 : zero-base

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;

/**
 * Counting Sort(계수 정렬)
 * - 숫자끼리 비교하지 않고 카운트를 세서 정렬하는 방식
 * - 카운팅을 위한 카운팅 테이블이 필요
 * - Un-Stable sort
 * - 시간 복잡도 = O(n+k)  (k는 정렬 대상 데이터 중 최대 값)
 * -
 * - [1,3,2,4,5] 이런 배열처럼 수의 분포가 좁다면 배열을 이용하는게 좋고
 * - [1,24005,4,3] 이런식으로 수 자체는 적은데 수의 분포가 넓다면 해시맵을 이용하는게 좋다.
 */

public class CountingSort {

    // 카운팅 테이블이 배열인 방식
    public static void countingSort1(int[] arr) {
        // 카운팅 테이블을 만들기 위해 가장 큰 값을 구해서
        int max = Arrays.stream(arr).max().getAsInt();

        // 가장 큰 값까지 들어갈 수 있는 테이블을 만든다. (인덱스가 0부터 시작하기 때문에 +1)
        // 만약 음수까지 나온다면 0을 기준으로 음수값최대 + 양수값 최대 + 1(0을 의미) 해주면된다
        int[] table = new int[max + 1];

        for (int i = 0; i < arr.length; i++) {
            // 배열 데이터 값을 키값으로 해서 테이블에 카운팅 (++)을 해준다.
            table[arr[i]]++;
        }

        int idx = 0;

        // 테이블 크기만큼 반복문 실행
        for (int i = 0; i < table.length; i++) {
            // 테이블에서 값이 0이 될 때까지 반복복            while (table[i] > 0) {
            // 원래의 배열에 값을 재배치 (음수가 있는 배열일 경우 0의 인덱스를 구해서 그만큼 빼주면 된다)
            arr[idx++] = i;
            table[i] -= 1;

        }
    }

    // 카운팅 테이블이 HashMap인 방식
    public static void countingSort2(int[] arr) {
        // 해시맵으로 테이블 생성
        HashMap<Integer, Integer> map = new HashMap<>();
        for (int i : arr) {
            map.put(i, map.getOrDefault(i, 0) + 1);
        }

        // 테이블의 키값을 오름차순 정렬렬
        ArrayList<Integer> list = new ArrayList<>(map.keySet());
        Collections.sort(list);

        int idx = 0;

        for (int i = 0; i < list.size(); i++) {

            // 원래 숫자
            Integer key = list.get(i);
            // 원래 숫자의 갯수
            Integer cnt = map.get(key);

            while (cnt > 0) {
                arr[idx++] = key;
                cnt--;
            }
        }
    }
}

'알고리즘 > 개념' 카테고리의 다른 글

정렬 알고리즘별 복잡도 정리  (0) 2022.04.30
Shell Sort (셸 정렬)  (0) 2022.04.30
Radix Sort (기수정렬)  (0) 2022.04.30
Heap Sort (힙 정렬)  (0) 2022.04.30
Merge Sort(합병 정렬, 2-ways 합병 정렬)  (0) 2022.04.29

댓글