Skip to content

Instantly share code, notes, and snippets.

@sohamb1390
Last active February 7, 2017 07:02
Show Gist options
  • Save sohamb1390/02bda3582cefac805a66ffef15211742 to your computer and use it in GitHub Desktop.
Save sohamb1390/02bda3582cefac805a66ffef15211742 to your computer and use it in GitHub Desktop.
Radix Sort of an unsorted list of numbers
//
// RadixSort.swift
// TestAutolayout
//
// Created by Soham Bhattacharjee on 06/02/17.
//
import UIKit
class RadixSort: NSObject {
// create an array of Ints from 0 - 9
static let originalBucket: Dictionary<String, [String]> = ["0": [], "1": [], "2": [], "3": [], "4": [], "5": [], "6": [], "7": [], "8": [], "9": []]
static func radixSort(list: inout [Int64]) {
// Output sortedArray
var listInString: [String] = []
listInString = list.map({"\($0)"})
// First get the biggest number from the list
guard let biggestElement = list.max() else {
return
}
// Check how many digits are there
// We have to continue 'passCount' number of passes to get the final result
let passCount = biggestElement.digitCounts
// If the number of digits is 1, then we can ensure that the list contains only one value. So we will return that one value itself since there is no need to sort
if passCount <= 1 {
return
}
// Append leading zeros to the rest of the elements whose number of digits are not equal to 'passCount'
for (index, item) in listInString.enumerated() {
// Get the difference between the number of digits of the biggest number and the rest of the
if passCount != Int64(item)!.digitCounts {
// Calculate the difference of number of digits between the largest number and the rest of the numbers in the list
let difference = passCount - Int64(item)!.digitCounts
var itemInString = item
for _ in 1...difference {
// Append a leading 0
let leadingZero = "0"
itemInString = leadingZero + itemInString
}
// Replace the previous element with this new one
listInString[index] = itemInString
}
//
print("Updated List: \(listInString)")
}
// Start the pass
RadixSort.radixPass(originalItemList: &list, itemList: &listInString, numberOfPass: Int(passCount - 1), bucket: originalBucket)
print("Final sorted List: \(list)")
}
static private func radixPass(originalItemList: inout [Int64], itemList: inout [String], numberOfPass: Int, bucket: Dictionary<String, [String]>) {
var bucketDict = bucket
for _ in 0...numberOfPass {
// start getting the item based on the first place from the right side of the digits in the item
for item in itemList {
let digit = Array(item.characters)[numberOfPass]
// Put the item into the bucket based on the digit
if Array(bucketDict.keys).contains("\(digit)") {
var arr = bucketDict["\(digit)"]
arr?.append(item)
bucketDict["\(digit)"] = arr
}
}
// take the numbers out of the bucket and sort again
print("Updated Bucket: \(bucketDict)")
var newItemList = RadixSort.getNewItemList(bucket: bucketDict)
print("New Item List after completing Pass-\(numberOfPass): \(newItemList)")
// Clear the bucket
bucketDict = originalBucket
if numberOfPass > 0 {
RadixSort.radixPass(originalItemList: &originalItemList, itemList: &newItemList, numberOfPass: numberOfPass - 1, bucket: originalBucket)
}
else {
// Now remove all the leading zeros by converting the String item list into Int item list
originalItemList = newItemList.map({Int64($0)!})
}
}
}
static private func getNewItemList(bucket: Dictionary<String, [String]>) -> [String] {
var counter = 0
var newItemList: [String] = []
while counter < 10 {
for item in bucket["\(counter)"]! {
newItemList.append(item)
}
counter += 1
}
return newItemList
}
}
extension Int64 {
public var digitCounts: Int64 {
get {
return Int64(numberOfDigits(in: self))
}
}
private func numberOfDigits(in number: Int64) -> Int {
if abs(number) < 10 {
return 1
}
else {
return 1 + numberOfDigits(in: number/10)
}
}
}
@sohamb1390
Copy link
Author

You can use this file by adding it to your project and invoke the radix sort by calling this method:

static func radixSort(list: inout [Int64])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment