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 a_{n-1}is greater than the next to last item a_{n-2}, swap them. Otherwise find the largest i such that a_{i}< a_{i+1}. Let a_{j}be the smallest value with j > i and a_{j}> a_{i}. Put a_{j}in position i, and fill positions a_{i+1}through a_{n-1}with the rest of the elements formerly in positions a_{i}through a_{n-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;`

Last modified 22 October 2003