Eazy's Radix Paper

History:
The radix sort was implemented back in the days where they used to use punch cards to input data. The use of the radix sort
Was used mainly for numerical information that required minimal bins to be used. Such as numbers that needs 10 bins.

Description:
The radix sort algorithm is a quick sorting method that checks a single place value and sorts by the appropriate bin location, then move one to the next highest place value and sorts to the appropriate bin until the highest place value has been visited where after the bins are appended to one another starting with the lowest bin number. To watch an example: (Scroll down at web page) http://ciips.ee.uwa.edu.au/~morris/Year2/PLDS210/radixsort.html

So sorting the following numbers: 30, 9, 0, 101, 19, 72

First: (ones place value) 3(0), (0), 10(1), 7(2), (9), 1(9)
After first pass: [30, 0] [101] [72] [9, 19] so 4 bins were used

Second: (tens place value) (0)0, 1(0)1, (0)9,(1)9,(3)0,(7)2
After second pass:[00, 101, 09] [19] [30] [72]

Third: (hundreds place value) (0)00, (0)09, (0)19, (0)30, (0)72, (1)01
After third pass: [000, 009, 019, 030, 072] [101]

Appends one bin to the other starting with lowest bin and gets 0, 9, 19, 30, 72, 101 sorted numbers

Demo:

Change the data in the HTML FORM below, click `go', and experiment. The contents of the array are shown after each pass. Sorting occurs at a given digit position and displayed in the trace window:

E
A
Z
Y

I
S

G
O
D
input:  
output:
trace:  

Analysis: Radix Sort runs in O(n) time. To explain how the sorting time is Big O(n) we need to look at n items in the range of 1 to m, where k bins must be allocated (ususally in radix sort its a sub number like the digits of base 10, 0 through 9 so 10 bins total), n items must be assigned to some bin. (n is the number of items to be sorted while k is the number of times the radix sort has to recurse) A value O(kn) is obtained, but k is a constant (usually not that large because this alorithms is usually used for small amounts of bins) and can be ignored if there is many n so O(n) is usually obtained.
     When comparing this algorithm with other algorithms such as selection, bubble, insertion, merge, quick, tree and heap sort you must consider that most algorithms do comparison while radix sort doesn't. Selection sort, sorts by swapping items and is usually good choice when data moves are costly but comparisons are not. Bubble sort, sorts by comparing two values and switching the higher one until all data has been checked. Use of the bubble sort would work great if all the data were sorted to begin with. Merge sort, is a recursive algorithm that breaks down arrays to single values, then recombines and sorts at the same time. This would be useful if memory wasn't an issue because some programs need to store data while others can just reference it. Quick sort, works by taking the first element in an array and using that as a pivot point to decide where the other elements in a list should go, if it's less than the pivot point it goes in one array and equal to or greater than to another array. From there it's sorted by a recursive call to quick sort again and appended to the original pivot point. Quick sort works well with large arrays and at least just as good as any comparison algorithm. Tree sort, takes the first node and making it the root node. From their comparison checks (which are at worst O(n)) are used to decide if a node should go on the left or right side of the root (where left being smaller, and right being larger or equal to depending how you want it). The data has been sorted and a tree traversal can be used to retrieve the data sorted such as a recursive in-order method. Tree sorting is good because unless the data has been given sorted already the Big-O will be less than n^2. Heap sort is type of sorting algorithm that sort by a modified version of a tree. The tree is always complete and the parent node is always larger than the children. This algorithm has at worse O(n * log n) and has an advantage over merge sort not needing a second array. All algorithms except for radix involved some kind of comparison. Radix sort doesn't do any comparison even though it needs to pass over a set of data more than once, it still retains worst case O(n) because the number of bins and times passed is dependant on the data that's being sorted. This would make these passes constant and constants are usually ignored when they become insignificant. (Such as large amounts of data) Other algorithms like insertion sort have a O(n^2) because it does comparison with two values to see if it is greater or less than something. This causes a comparison check to see where a value goes then a second iterative statement puts it into its right locations. So as you can see radix sort would be good way of sorting numbers but if we were trying to sort names that can have any symbol in ASCII set then insertion sort may be better.

Selection Sort : n^2
Bubble Sort:     n^2
Insertion Sort:   n^2
Merge Sort:      n^2
Quick Sort:       n^2
Radix Sort:        n
Treesort:           n^2
Heapsort:         n*log n


Sample Code:

/******************************************************/
/* RadixSort.c */
/* */
/* Radix sort demonstration. */
/* Author: Rick Coleman */
/* Date: April 1998 */
/******************************************************/
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include "sort.h"

#define RADIX 10
#define ARRAYMAX 32
#define MAXKEY 9999

/* Prototype sort function */
void RadixSort(StructType DataArray[], StructType DataArray2[], int count);

int main(void)
{
StructType DataArray[ARRAYMAX], DataArray2[ARRAYMAX];
int count;

count = ReadRecords(DataArray, ARRAYMAX);
printf("Unsorted list of records.\n\n");
PrintList(DataArray, count);

RadixSort(DataArray, DataArray2, count);

printf("Sorted list of records.\n\n");
PrintList(DataArray2, count);
printf("Sorting done...\n");
getch();
return(0);
}


/***************************************/
/* RadixSort() */
/* */
/* Sort records on integer key using */
/* a radix sort. */
/* Note: This sort is made faster by */
/* using two arrays of pointers to */
/* structs. The structures are then */
/* sorted by moving the pointers */
/* instead of the structures themselves*/
/* This speeds up the sort because it */
/* is much quicker to move a 4-byte */
/* pointer than it is a large struct. */
/***************************************/
void RadixSort(StructType DataArray[], StructType DataArray2[], int count)
{
int i, j, k, radixN, radixNplus1, index;
StructType *temp1[ARRAYMAX], *temp2[ARRAYMAX];
StructType **arrayIn, **arrayOut, **arrayTemp;

/* Create initial array of pointers to structs */
for(i=0; i<count; i++) temp1[i] = &DataArray[i];

/* Set initial pointers to arrays of pointers */
arrayOut = &temp1[0];
arrayIn = &temp2[0];


for(i=0; i<(int)ceil(log10(MAXKEY)); i++) /* Get # digits in the key, i.e. ceil(log10(9999)) = 4 */
{
index = 0; /* Start at beginning of arrays of pointers */
radixN = (int)ceil(pow(RADIX, i));
radixNplus1 = radixN * RADIX;

for(j=0; j<RADIX; j++) /* Sort into 10 stacks */
{
for(k=0; k<count; k++) /* Look at all records */
{
/* To isolate one digit: (num % radixi+1 ) / radixi */
if( ( (int)floor(((*(arrayOut+k))->key % radixNplus1) / radixN)) == j)
{
/* Copy the pointer */
*(arrayIn+index) = *(arrayOut + k);
printf("Key moved = %.4d\n", (*(arrayIn+index))->key);
getch();
index++;
}
}
}
/* Swap the array pointers */
arrayTemp = arrayOut;
arrayOut = arrayIn;
arrayIn = arrayTemp;
}

/* Copy structs from Array1 in sorted order into Array2 */
/* Use arrayOut here as it was the result of the last */
/* sorting after the pointers were swapped. */
for(i=0; i<count; i++)
DataArray2[i] = *(*(arrayOut + i));
}

Bibliography:

http://ciips.ee.uwa.edu.au/~morris/Year2/PLDS210/radixsort.html : Date: 04/23/2002
http://www.nist.gov/dads/HTML/radixsort.html : Date: 04/23/2002
http://www.cs.uah.edu/~rcoleman/Sorting/RadixSort.html : Date: 04/23/2002