# CMPSCI 311: Theory of Algorithms

### Fun With Permutations

Questions in black, solutions in blue.

The permutations of an n-element set are the n! different listings of it as a sequence. Here is a Java class that stores a permutation as an array of `int` variables with the numbers {1,...,n} in some order. The second array `arrow` is used in the Johnson-Trotter algorithm below.

``````
public class Permutation
int n; // size of set
int [] a; // values from 1 through n in some order
boolean [] arrow; // true means left, false means right

public Permutation (size)
{// creates new identity permutation of given size
n = size;
a = new int[n];
arrow = new boolean[n];
for (int i=0; i < n; i++)
{a[i] = i+1; arrow[i] = true;}

public void swap (int i, int j)
{// swaps both value and arrow in position i and j
int ti = a[i]; a[i] = a[j]; a[j] = ti;
boolean tb = arrow[i]; arrow[i] = arrow[j]; arrow[j] = tb;}
``````

• Question 1: Write a `boolean` method `next()` that changes the calling Permutation into the next one given by the Johnson-Trotter method, updating the arrows. Levitin's description of the process is ``if there is a mobile integer k, find the largest one, swap it with the neighbor it points to, and reverse the arrows of all integers larger than k''. ``Mobile'' means ``pointing to a smaller integer''. Your method should return `true` if the update happens, or `false` if there is no mobile integer.

This method would be used as follows to print all the permutations of size n:

``````
Permutation p = new Permutation(n);
boolean done = false;
while (!done) {
System.out.println(p); // using a "toString" method to be written
done = !p.next();}
``````

``````
public boolean mobile (int i)
{//returns whether item i of calling object points to smaller item
if ((i > 0) && (a[i-1] < a[i])) return true; // "&&" is important
if ((i < n-1) && (a[i+1] < a[i])) return true; // here as well
return false;}

public boolean next()
{//changes calling object to next on in Johnson-Trotter order
//locate mobile item with largest value
int k = 0, kspot = 0; // will be largest mobile and its location
int place = 1;
while (place < n) {
while (!mobile(place)) place++;
if (a[place] > k) {
k = a[place]; kspot = place;
place++;}
if (k == 0) return false; // if so there was no mobile at all
if (arrow[kspot]) swap (kspot, kspot-1);
else swap (kspot, kspot+1);
for (place = 0; place < n; place++)
if (a[place] > k) arrow[place] = !arrow[place];
return true;}
``````

• Question 2: Write a `boolean` method `lex` that changes the calling Permutation to the next one in lexicographical order. Ignore the arrows. Levitin gives an outline for this: ``If the last item an-1 is greater than the next to last item an-2, swap them. Otherwise find the largest i such that ai < ai+1. Let aj be the smallest value with j > i and aj > ai. Put aj in position i, and fill positions ai+1 through an-1 with the rest of the elements formerly in positions ai through an-1, in increasing order.'' (I found the easiest way to do this was to make a new array b element by element, without changing a, and then assign b to a.)

Again, your method should return `true` if the change is made and `false` if the current Permutation is already last in lexicographic order.

``````        public boolean lex()
{// changes calling object to next permutation in lex order
// ignores arrow field of calling object, may mess up "next"
int try; // loop index
if (n == 1) return false;
if (a[n-1] > a[n-2]) {swap(n-1, n-2); return true;}
int i; boolean found = false;
for (try = 0; try < n-1; try++)
if (a[try] < a[try+1]) {
found = true;
i = try;}
if (!found) return false; // calling permutation is reverse order
// now i is last item before descending sequence i+1..n
int j = i, best = n+1;
for (try = i+1; i < n; i++)
if ((a[try] < best) && (a[try] > a[i])) {
best = a[try];
j = try;}
// assemble answer in new array, could avoid this by right swaps
int[] b = new int[n];
for (try = 0; try < i; try++) b[try] = a[try];
b[i] = a[j];
int bspot = i+1;
// now copy a[i] through a[n-1], excepting a[j], into b in order
swap(i,j); // now a[i+1] through a[n-1] are right elements in
// reverse order -- we've altered a but that's ok
for (try = n-1; try > i; try--) {
b[bspot] = a[try];
bspot++;}
a = b;
return true;
``````