# CMPSCI 311: Theory of Algorithms

### from Wednesday 5 Nov 2003

Questions are in black, answers in blue.

Here we will use the main idea of Levitin 7.1 to implement a radix sort of strings.


public class StringArray
int n; // length of array
int k; // length of each string
String [] a; // the array of n strings, each must be of length k

public void sortBy (int i)
{// does stable sort on array a by the i'th letter of the strings

public void sort()
{// sorts strings in a lexicographically


• Question 1: Implement the sortBy method, asuming that all the characters in all the strings in the StringArray are ASCII (each character is in the range from 0 through 127 when viewed as a number). Your method should run in O(n) time, treating 128 as a constant. It is all right to make a second array of $n$ strings if you like. Recall that you can cast a character to an int by the operator (int)'' or just by using the character where an int is called for.


public void sortBy (int i)
{// does stable sort on array a by the i'th letter of the strings
int[] count = new int[128];   // how many with each i'th letter
int[] next = new int[128];    // position for next string with letter
String [] b = new String[n];  // temporary to assemble sorted version
for (int j=0; j < n; j++)
count[a[j].charAt(i)]++;
for (int j=1; j < n; j++)
next[j] = next[j-1] + count[j-1]; // so next[i] is sum of counts < i
for (int j=0; j < n; j++) {
b[next[a[j].charAt(i)] = a[j];
next[a[j].charAt(i)]++;}
a = b;}


This is pretty similar to the pseudocode on Levitin page 249. (Levitin saves a little space by overwriting my "next" into "count".) Given j and z, the z'th element with charAt(i) = j is going into the location given by next[j] when it is moved, and this will be z-1 plus the original value of next[j], or z-1 plus the sum of count[y] for all y less than j. Timing is clearly Θ(n) since the loops execute n, n-1, and n times respectively.

• Question 2: Implement the sort method using {\it radix sort} as follows: By applying the different sortBy operations for the various values of i in the right order, and using the fact that sortBy is stable, you can sort the strings completely using O(nk) total time. Give code for this and argue that your code sorts correctly.


public void sort()
{// does radix sort of array a
for (int j=k-1; j >= 0; j--)
sortBy(j);}


Clearly this is Θ(kn) time because it makes k calls to sortBy. Why is it correct? We need to show that for any two strings u and v, each of length k, if u and v both occur in the array a and u is lexicographically before v, then u will be placed before v in the output. Let u and v be arbitrary strings meeting these conditions.

Since u is before v, there exists some number i such that u.charAt(i) comes before v.charAt(i), and u.charAt(j) equals v.charAt(j) for all j less than i. When the sort algorithm runs sortBy(i), u will be placed before v. When it then runs sortBy(j) for each j less than i, the j'th characters of the two strings will be equal, and then u will remain before v because sortBy is a stable sort and preserves the order of elements that are tied in its order. So at the end of the run of sort, u is before v as desired. Since u and v were arbitrary, we conclude that sort sorts correctly.