2017. 1. 6. 15:34ㆍETC/Algorithm Concept
기수 정렬이란?
기수 정렬(radix sort)은 낮은 자리수부터 비교하여 정렬해 간다는 것을 기본 개념으로 하는 정렬 알고리즘이다. 자릿수가 고정되어 있으니, 안정성이 있고(이때 데이터들 간의 상대적 순서는 보존되어야 한다.) 시간 복잡도는 이다.(는 가장 큰 데이터의 자리수)
기수 정렬은 비교 연산을 하지 않으며, 무엇보다도 전체 시간 복잡도 역시 이어서, 정수와 같은 자료의 정렬 속도가 매우 빠르다. 하지만, 데이터 전체 크기에 기수 테이블의 크기만한 메모리가 더 필요하다. 기수 정렬은 정렬 방법의 특수성 때문에, 부동소수점 실수처럼 특수한 비교 연산이 필요한 데이터에는 적용할 수 없지만, 사용 가능할 때에는 매우 좋은 알고리즘이다.
출처: https://ko.wikipedia.org/wiki/%EA%B8%B0%EC%88%98_%EC%A0%95%EB%A0%AC (위키백과)
위키백과에 위와 같은 내용으로 정의되어있다. 이 기수정렬을 처음 알았을 때는 정말 신기하였다. 이렇게 자릿수마다 비교하고서 마지막에는 정렬된 상태가 나오기 때문이다. 도대체 이걸 생각한 사람도 대단하다고 느꼈다. 기수정렬의 원리는 아래 그림과 같다.
그림을 보면 data 배열을 만들고서 그 안에는 앞으로 정렬할 데이터를 입력합니다. Bucket에는 0~9까지 index를 중심으로 data를 입력합니다. 위의 그림을 보면 231,152,675,442 4개의 숫자를 정렬해보았습니다. 이 숫자들의 일의 자리, 십의 자리, 백의 자리 순으로 정렬하는 것이 이 정렬의 원리입니다.
처음에 일의 자리로 정렬하였더니
231 에서 일의 자리인 1을 bucket의 index 주소 1의 자리에다가 추가합니다.
152 에서 일의 자리인 2를 bucket의 index 주소 2의 자리에다가 추가합니다.
675 에서 일의 자리인 5를 bucket의 index 주소 5의 자리에다가 추가합니다.
442 에서 일의 자리인 2를 bucket의 index 주소 2의 자리에다가 추가합니다.
그리고서 위의 자리에서부터 숫자를 data[] 배열에 입력합니다.
그러면 data[]배열의 index안에는 231,152,442,675 값이 입력됩니다. 이런 식으로 십의 자리, 백의 자리까지 한다면 마지막으로 152,231,442,675 로 정렬된 상태가 됩니다. 아래는 제가 직접 짠 소스입니다.
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | import java.io.*; import java.util.StringTokenizer; /** * on 31/12/2016. */ class Bucket { int data; Bucket node; public Boolean isEmpty() { if (this.node == null) { return true; } return false; } public int getData() { return data; } public void setData(int data) { this.data = data; } public Bucket getNode() { return node; } public void setNode(Bucket node) { this.node = node; } Bucket(int data) { this.data = data; } Bucket(Bucket node) { this.node = node; } } public class RadixSort { Bucket[] bucketArr = new Bucket[10]; Bucket[] data; void inputNumber() throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine().trim()); int n = Integer.parseInt(st.nextToken());//숫자 갯수 입력 // int n = 4; data = new Bucket[n];//숫자 저장소 // data[0] = new Bucket(231); // data[1] = new Bucket(152); // data[2] = new Bucket(675); // data[3] = new Bucket(442); for (int i = 0; i < n; i++) { st = new StringTokenizer(br.readLine().trim()); data[i] = new Bucket(Integer.parseInt(st.nextToken())); } } void sort() throws IOException { inputNumber(); // display(); Boolean keepGoing = true; int cnt = 1; int bucketNum = 0; int index = 0; while (keepGoing) { keepGoing = false; for (int i = 0; i < data.length; i++) { //Bucket에 Data 넣기 int num = data[i].getData(); for (int k = 0; k < cnt; k++) { //자릿수 bucketNum = num % 10; num /= 10; } if (bucketNum != 0) { keepGoing = true; } //Number number = new Number(data[i].getNum()); if (bucketArr[bucketNum] == null) { bucketArr[bucketNum] = data[i]; } else { Bucket temp = data[i]; Bucket head = bucketArr[bucketNum]; while (head.node != null) { head = head.node; } head.node = temp; } } //Bucket에 순서대로 빼기 index = 0; for (int i = 0; i < bucketArr.length; i++) { if (bucketArr[i] != null) { Bucket temp = bucketArr[i]; do { data[index] = temp; temp = temp.node; data[index++].node = null;//data[]에 들어가면 링크 삭제 } while (temp != null); } } bucketInit(); cnt++; } display(); } void bucketInit() { //bucketArr 초기화 for (int i = 0; i < bucketArr.length; i++) { bucketArr[i] = null; } } void display() throws IOException { // for (int i = 0; i < data.length; i++) { // System.out.print(data[i].getData() + " "); // } // System.out.println(); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); for (int i = 0; i < data.length; i++) { bw.write(String.valueOf(data[i].getData()) + "\n"); } bw.close(); } public static void main(String[] args) throws IOException { new RadixSort().sort(); } } | cs |
'ETC > Algorithm Concept' 카테고리의 다른 글
Linked List는 무엇인가? (0) | 2024.02.11 |
---|---|
Bubble Sort(버블정렬) (0) | 2022.01.25 |
Insert Sort(삽입정렬) (0) | 2020.03.19 |
Kadane 알고리즘 (0) | 2017.07.25 |
계수 정렬(Counting Sort) java (0) | 2016.12.27 |