Задача. Напечатать все перестановки чисел 1..n (то есть последовательности длины n, в которые каждое из чисел 1..n входит по одному разу).
Решение. Перестановки будем хранить в массиве x[1],...,x[n] и печатать в лексикографическом порядке. (Первой при этом будет перестановка < 1 2...n >, последней - < n...2 1 >.) Для составления алгоритма перехода к следующей перестановке зададимся вопросом: в каком случае k-ый член перестановки можно увеличить, не меняя предыдущих? Ответ: если он меньше какого-либо из следующих членов (членов с номерами больше k). Мы должны найти наибольшее k, при котором это так, т. е. такое k, что x[k] < x[k+1] > ... > x[n]. После этого x[k] нужно увеличить минимальным возможным способом, т. е. найти среди x[k+1], ..., x[n] наименьшее число, большее его. Поменяв x[k] с ним, остается расположить числа с номерами k+1, ..., n так, чтобы перестановка была наименьшей, то есть в возрастающем порядке. Это облегчается тем, что они уже расположены в убывающем порядке.
Алгоритм перехода к следующей перестановке.
{ < x[1],...,x[n-1], x[n]> < > < n,...,2, 1>.}
k:=n-1;
{последовательность справа от k убывающая: x[k+1] >...> x[n]}
while x[k] > x[k+1] do begin
k:=k-1;
end;
{x[k] < x[k+1] > ... > x[n]}
t:=k+1;
{t <=n, x[k+1] > ... > x[t] > x[k]}
while (t < n) and (x[t+1] > x[k]) do begin
t:=t+1;
end;
{x[k+1] > ... > x[t] > x[k] > x[t+1] > ... > x[n]}
... обменять x[k] и x[t]
{x[k+1] > ... > x[n]}
... переставить участок x[k+1] ... x[n]
в обратном порядке
Замечание. Программа имеет знакомый дефект: если t = n, то x[t+1] не определено.