입력값을 자릿수별로 구분해서 부분적으로 비교하여 정렬하는 방식
낮은 자리부터 높은 자리로 진행(Right-to-Left)
높은 자리부터 낮은 자리로 진행(Left-to-Right)
import java.util.Arrays;
public class RadixSort {
/**
* 기수 정렬 메서드
*/
public static void radixSort(int[] array) {
// 입력 배열의 최대값 찾기
int max = Arrays.stream(array).max().getAsInt();
// 최댓값의 자릿수 구하기
int maxDigit = (int) Math.log10(max) + 1;
for (int exponent = 1; exponent <= maxDigit; exponent++) {
countingSort(array, exponent);
}
}
/**
* 기수에 따라 배열을 정리하는 메서드
*/
private static void countingSort(int[] array, int exponent) {
int length = array.length;
int[] output = new int[length];
int[] count = new int[10]; // 자릿수(0~9)를 처리하기 위한 카운트 배열
// 각 자릿수별로 개수 세기
for (int index = 0; index < length; index++) {
int digit = (array[index] / exponent) % 10;
count[digit]++;
}
// count 배열을 업데이트하여 각 값의 누적 등장 횟수 계산
for (int index = 1; index < 10; index++) {
count[index] += count[index - 1];
}
// output 배열 생성
for (int index = length - 1; index >= 0; index--) {
int digit = (array[index] / exponent) % 10;
output[count[digit] - 1] = array[index];
count[digit]--;
}
// output 배열을 array에 복사
System.arraycopy(output, 0, array, 0, length);
}
/**
* 배열 출력 메서드
*/
public static void printArray(int[] array) {
System.out.println(Arrays.toString(array));
}
public static void main(String[] args) {
int[] array = {170, 45, 75, 90, 802, 24, 2, 68};
System.out.print("기수 정렬 전 배열 : ");
printArray(array);
radixSort(array);
System.out.print("기수 정렬 후 배열 : ");
printArray(array);
}
}
import java.util.Arrays;
public class RadixSort {
/**
* 기수 정렬 메서드
*/
public static void radixSort(int[] array) {
int max = Arrays.stream(array).max().getAsInt();
radixSort(array, 0, array.length - 1, max);
}
/**
* 기수 정렬 재귀 메서드
*/
private static void radixSort(int[] array, int low, int high, int exponent) {
if (low >= high || exponent <= 0) {
return;
}
int[] output = new int[array.length];
int[] count = new int[10];
// 각 자릿수별로 개수 세기
for (int index = low; index <= high; index++) {
int digit = (array[index] / exponent) % 10;
count[digit]++;
}
// count 배열을 업데이트하여 각 값의 누적 등장 횟수 계산
for (int index = 1; index < 10; index++) {
count[index] += count[index - 1];
}
// output 배열 생성
for (int index = high; index >= low; index--) {
int digit = (array[index] / exponent) % 10;
output[count[digit] - 1] = array[i];
count[digit]--;
}
// output 배열을 array에 복사
System. arraycopy(output, 0, array, low, high - low + 1);
// 각 자릿수별로 재귀적으로 기수 정렬 수행
for (int index = 0; index < 10; index++) {
radixSort(array, low + count[index], low + count[index + 1] - 1, exponent / 10);
}
}
/**
* 배열 출력 메서드
*/
public static void printArray(int[] array) {
System.out.println(Arrays.toString(array));
}
public static void main(String[] args) {
int[] array = {170, 45, 75, 90, 802, 24, 2, 68};
System.out.print("기수 정렬 전 배열 : ");
printArray(array);
radixSort(array);
System.out.print("기수 정렬 후 배열 : ");
printArray(array);
}
}
/**
* 기수 정렬 메서드
*/
public static void radixSort(int[] array) {
// 입력 배열의 최대값 찾기 : O(n)
int max = Arrays.stream(array).max().getAsInt();
// 최댓값의 자릿수 구하기 : O(1)
int maxDigit = (int) Math.log10(max) + 1;
for (int exponent = 1; exponent <= maxDigit; exponent++) {
countingSort(array, exponent);
}
}
/**
* 기수에 따라 배열을 정리하는 메서드
*/
private static void countingSort(int[] array, int exponent) {
int length = array.length;
int[] output = new int[length];
int[] count = new int[10];
// 각 자릿수별로 개수 세기 : O(n)
for (int index = 0; index < length; index++) {
int digit = (array[index] / exponent) % 10;
count[digit]++;
}
// count 배열을 업데이트하여 각 값의 누적 등장 횟수 계산 : O(k)
for (int index = 1; index < 10; index++) {
count[index] += count[index - 1];
}
// output 배열 생성 : O(n)
for (int index = length - 1; index >= 0; index--) {
int digit = (array[index] / exponent) % 10;
output[count[digit] - 1] = array[index];
count[digit]--;
}
// output 배열을 array에 복사 : O(n)
System.arraycopy(output, 0, array, 0, length);
}
O(n)
/**
* 기수 정렬 메서드
*/
public static void radixSort(int[] array) {
int max = Arrays.stream(array).max().getAsInt(); // O(n)
radixSort(array, 0, array.length - 1, max);
}
/**
* 기수 정렬 재귀 메서드
*/
private static void radixSort(int[] array, int low, int high, int exponent) {
if (low >= high || exponent <= 0) {
return;
}
int[] output = new int[array.length];
int[] count = new int[10];
// 각 자릿수별로 개수 세기 : O(n)
for (int index = low; index <= high; index++) {
int digit = (array[index] / exponent) % 10;
count[digit]++;
}
// count 배열을 업데이트하여 각 값의 누적 등장 횟수 계산 : O(k)
for (int index = 1; index < 10; index++) {
count[index] += count[index - 1];
}
// output 배열 생성 : O(n)
for (int index = high; index >= low; index--) {
int digit = (array[index] / exponent) % 10;
output[count[digit] - 1] = array[i];
count[digit]--;
}
// output 배열을 array에 복사 : O(n)
System. arraycopy(output, 0, array, low, high - low + 1);
// 각 자릿수별로 재귀적으로 기수 정렬 수행 : O(k)
for (int index = 0; index < 10; index++) {
radixSort(array, low + count[index], low + count[index + 1] - 1, exponent / 10);
}
}
O(n)
O(dn)
O(n)
📖 참고
- 이관용, 김진욱(2024). 알고리즘. 한국방송통신대학교출판문화원