// file: radixsort.java // author: Robert Keller // purpose: illustrating a very fast sorting program for natural numbers only import java.lang.*; import java.io.*; import java.util.*; class radixsort { /** * Calling radixsort constructor on array of floats sorts the array. * Parameter N is the number of elements to be sorted. **/ // radixsort works using binary representation of numbers being sorted. // It first sorts on the least-significant bit, then the next least, // and so on until there are no more bits which have 1 as a value. // On each pass, it counts the number of words with a 0 in the current // bit position. It then copies the elements from the array into a // buffer so that all words with a 0 precede all with a one. It then // copies the buffer back to the array for the next pass. radixsort(int array[], int N) { int buffer[] = new int[N]; // place to put result of one pass boolean done = false; // indicates whether sorting completed for( int shiftAmount = 0; !done; shiftAmount++ ) { // one pass consists of the following: int count = 0; // count of number of 0 bits done = true; // first phase: determine number of words with 0 bit for( int i = 0; i < N; i++ ) { int shifted = (array[i] >> shiftAmount); // move bit to low-order if( shifted > 0 ) // is there anything left? done = false; if( shifted % 2 == 0 ) count++; // count this 0 } if( done ) break; // second phase: redistribute words with 0 vs. 1 int lower = 0, upper = count; // positions for redistribution for( int i = 0; i < N; i++ ) { int shifted = (array[i] >> shiftAmount); if( shifted % 2 == 0 ) { buffer[lower++] = array[i]; } else { buffer[upper++] = array[i]; } } for( int i = 0; i < N; i++ ) { array[i] = buffer[i]; } } } /** * test program for radixsort; reads arbitrarily-many numbers * from standard input, sorts them, then writes them to standard output. **/ public static void main(String[] args) { StreamTokenizer in = new StreamTokenizer(System.in); int Size = 1; // initial allocation int N = 0; // number of elements in array int array[] = new int[Size]; // initial array allocation try { // while more numbers in file while( in.nextToken() != java.io.StreamTokenizer.TT_EOF ) { if( N == Size ) // if the array is full { array = reallocate(array); // int the array size Size *= 2; } array[N++] = (int)in.nval; // put item in array } } catch(IOException e) { System.err.println("*** IOException caught"); } Date startTime = new Date(); System.err.println("Sorting started"); new radixsort(array, N); // calling constructor sorts Date endTime = new Date(); long time = endTime.getTime() - startTime.getTime(); System.err.println("Sorting finished in " + time + " ms"); for( int i = 0; i < N; i++ ) { System.out.print(array[i] + " "); } System.out.println(); System.err.println("Sorting " + N + " elements using radixsort took " + time + " ms"); } /** * reallocate allocates a new array int the size of the original * and copies the original into it. The new array is returned. **/ static int[] reallocate(int array[]) { int[] newArray = new int[2*array.length]; for( int i = 0; i < array.length; i++ ) // copy old array newArray[i] = array[i]; return newArray; } }