[Data Structure] 기수 정렬 - Radix Sort
2021. 12. 31. 20:37ㆍMajor`/자료구조
기수 정렬 (Radix Sort)

Stable Sort
- 비교하지 않는 정렬 알고리즘
- 기수(radix) = 숫자의 자리수 → ex) 42 = 4와 2의 2개의 자리수 보유
- 십진수에서 각 자리수는 0~9까지의 값만 가지기 때문에 10개의 버킷을 생성해서 (0, 1, 2,....9) 숫자의 기수에 맞게 버킷에 집어넣는다
- 낮은 숫자의 버킷부터 차례대로 해당 버킷의 값을 꺼내면서 정렬
- 큐(Queue)로 구현하면 편리하게 구현 가능
숫자가 10 이상일 경우
1. 자릿수가 2개가 존재하기 때문에, 먼저 1의 자리수를 기준으로 버킷에 집어넣는다
2. 1의 자리수를 기준으로 insert된 버킷에서 각 숫자를 꺼낸다음에 십의 자리수를 기준으로 버킷에 집어넣고, 버킷에서 꺼내면 정렬이 완료된다
정렬할 배열 A, 10개의 Bucket 필요 (0 ~ 9)
시간복잡도
- O(nk) → k = 자릿수 개수
장점
- O(n)의 매우 빠른 속도로 정렬 가능
단점
- 정렬할 수 있는 레코드의 타입이 동일한 길이를 가지는 숫자/문자열로 한정되어 있다
- 추가적인 메모리가 필요하다
과정
- 10개의 Bucket 준비 (Bucket : 0 ~ 9)
- 배열의 요소 중 최대 자릿수를 가지는 요소의 자릿수 return
- 배열의 각 요소들의 1의 자릿수를 기준으로 Queue에 각각 삽입
- Queue 0 ~ 9까지 차례대로 요소들을 꺼내서 배열에 다시 저장
- 배열의 각 요소들의 10의 자릿수를 기준으로 다시 Queue에 각각 삽입
- Queue 0 ~ 9 까지 차례대로 요소들을 꺼내면 정렬 완료




Radix_Sort Code
static void radix_sort(int[] A, LinkedList[] bucket, int[] result){ for(int i=0; i<10; i++) bucket[i] = new LinkedList<>(); // bucket 10개 생성 int radix = 1; while(radix<get_max_radix(A)) radix*=10; // 요소 중 최댓값의 자릿수 확인 for(int i=1; i<radix; i*=10){ for(int j=0; j<A.length; j++){ int p = (A[j]/i)%10; // 각 숫자의 자릿수(작은 자릿수부터) bucket[(A[j]/i)%10].offer(A[j]); } int index = 0; for(int k=0; k<10; k++){ while(bucket[k].size() != 0){ A[index] = (int) bucket[k].peekFirst(); bucket[k].pollFirst(); index++; } } for(int i=0; i<A.length; i++) result[i] = A[i]; }
Full Code
package Sort; import java.util.*; public class Radix_Sort_2 { public static void main(String[] args) { int [] A = new int[30]; // 정렬할 배열 A int [] result = new int[30]; // A의 최종 정렬 배열 저장 LinkedList [] bucket = new LinkedList[10]; // 0 ~ 9 저장하는 bucket 10개 for(int i=0; i<A.length; i++) A[i] = (int)(Math.random()*201); // 0~200 // 정렬 전 A 출력 System.out.println("A[]"); for(int i=0; i<A.length; i++){ if(i%10==0) System.out.println(); System.out.print(A[i] + "\t"); } System.out.println("\n"); radix_sort(A, bucket, result); } static int get_max_radix(int [] A){ // 요소 중 자릿수 최대인 요소 int max = A[0]; for(int i=1; i<A.length; i++){ if (A[i] > max) max = A[i]; } return max; } static void radix_sort(int[] A, LinkedList[] bucket, int[] result){ for(int i=0; i<10; i++) bucket[i] = new LinkedList<>(); // bucket 10개 생성 int radix = 1; while(radix<get_max_radix(A)) radix*=10; // 요소 중 최댓값의 자릿수 확인 Calendar before = Calendar.getInstance(); for(int i=1; i<radix; i*=10){ for(int j=0; j<A.length; j++){ int p = (A[j]/i)%10; // 각 숫자의 자릿수(작은 자릿수부터) bucket[(A[j]/i)%10].offer(A[j]); } int index = 0; for(int k=0; k<10; k++){ while(bucket[k].size() != 0){ A[index] = (int) bucket[k].peekFirst(); bucket[k].pollFirst(); index++; } } // radix 별 정렬 System.out.println(i + "의 자리 정렬 []"); for(int t=0; t<A.length; t++){ if(t%10==0) System.out.println(); System.out.print(A[t] + "\t"); } System.out.println("\n"); } Calendar after = Calendar.getInstance(); for(int i=0; i<A.length; i++) result[i] = A[i]; // 정렬 후 최종 result 배열 출력 System.out.println("result[]"); for(int i=0; i<result.length; i++){ if(i%10==0) System.out.println(); System.out.print(result[i] + "\t"); } System.out.println("\n"); int time = after.get(Calendar.MILLISECOND) - before.get(Calendar.MILLISECOND); System.out.println("걸린 시간 : " + time + "ms"); } }


