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 |
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