지금까지는 정렬 순서를 결정하기 위해 비교에 의존해왔다.
Radix Sort 는 선형 시간안에 정렬이 가능한, non-comparative algorithm이다.
기수정렬은 자리수를 비교한다.
예시 배열 [88, 410, 1772, 20] 이 있다고 하자.
1의 자리 비교
1의 자리를 비교하면 0, 2, 8이다. → 이 순서대로 정렬하면 [410, 20, 1772, 88] 순서로 정렬된다.
10의 자리 비교
1에서 정렬된 배열에서 10의 자리를 비교하면, 1, 2, 7, 8 순서이다. 이 순서대로 정렬하면,
[410, 20, 1772, 88] 이다. 변경된게 없으므로 다음으로 넘어간다.
100의 자리 비교
100의 자리 숫자만으로 비교하면, 4, 0, 7, 0 이다. (해당 자릿수가 없으면 0으로 취급한다)
이를 정렬하면 0, 4, 7이고 이 순서대로 배열을 정렬하면
[20, 88, 410, 1772] 가 된다.
1000의 자리 수 비교
1000의 자리 숫자만으로 비교하면, 0, 1 이다. 0인 경우는 20, 88, 410 이 하나의 bucket에 있고, 1의 경우는 1772 하나 뿐이다.
같은 bucket 내에서의 정렬 순서는 앞선 단계에서 이미 정렬된 상태이다!
extension Array where Element == Int {
public mutating func radixSort() {
}
}
public mutating func radixSort() {
let base = 10
var done = false // 정렬이 완료되었는지 체크
var digits = 1 //
while !done {
}
}
for 문 안에서는 같은 bucket 안에 들어있는 숫자들을 정렬하기 위한 bucket sort 가 필요하다.
// 1. 이차원 배열로 초기화 -> 10개의 빈 배열을 가짐
// 각 자릿수별로 숫자를 그룹핑하는 역할을 함
// 1의 자릿수가 5인 숫자는 bucket[5]에 저장되겠지
var buckets: [[Int]] = .init(repeating: [], count: base)
// 2.
forEach { number in
// digits 는 현재 정렬할 자릿수
let remainingPart = number / digits
// remainingPart에서 base로 나눈 나머지 값. -> 이건 해당 자릿수에서의 값을 알 수 있음
let digit = remainingPart % base
// 계산된 자릿수에 해당하는 버킷에 숫자 추가
// 1의 자릿수에 3이 있다면, buckets[3]에 숫자 추가
buckets[digit].append(number)
}
// 3.
// digits는 1로 시작
// 매 루프때마다 10을 곱해 점점 더 높은 자릿수로 가도록 함
digits *= base
// 10개의 버킷에 분류된 숫자들을 하나의 배열로 다시 합치는 작업
// flatMap을 통해 2차원 배열을 1차원 배열로 만든다
self = buckets.flatMap { $0 }
done 을 루프 돌기 시작할 때 true로 설정한다.
forEach 문 안에서 remainingPart가 있을 때 done 을 설정하여 필요한 경우 계속 while 문을 돌 수 있도록 한다. (이 말은 남아있지 않으면 while 문을 탈출 할 수 있는 것.
if remainingPart > 0 {
done = false
}
public mutating func radixSort() {
let base = 10
var done = false
var digits = 1
while !done {
done = true
/* 여기서부터 bucket sort */
var buckets: [[Int]] = .init(repeating: [], count: base)
forEach { number in
let remainingPart = number / digits
let digit = remainingPart % base
buckets[digit].append(number)
if remainingPart > 0 {
done = false
}
}
digits *= base
self = buckets.flatMap { $0 }
}
}