Наиболее естественным выглядит результат
перечисления перестановок в
лексиграфическом порядке, где каждая следующая перестановка образует лексиграфически больший вектор своих элементов, чем любая из предыдущих. В общем случае из двух любых векторов равной длины лексиграфически большим считается тот вектор, у которого больше первый из несовпадающих элементов. Применительно, например, к цифровым перестановкам лексиграфический порядок порождает возрастающую последовательность натуральных чисел, которые получаются из записей соответствующих перестановок. В частности, все перестановки из трех цифр
1,
2 и
3 образуют следующую лексиграфически упорядоченную числовую последовательность:
ПL: (123) < (132) < (213) < (231) < (312) < (321).
Лексиграфический порядок перестановок букв любых национальных алфавитов соответствует расположению образованных из них слов как в словаре. Например, перестановки латинских букв
X,
Y и
Z могут быть перечислены в следующем лексиграфическом порядке, который часто называется словарным порядком:
ПL: (XYZ) < (XZY) < (YXZ) < (YZX) < (ZXY) < (ZYX).
Однако без потери общности последующего описания лексиграфического алгоритма удобно рассматривать перечисление перестановок целых чисел от 1 до n. Этот алгоритм реализует итерационный процесс, который начинается с лексиграфически наименьшей перестановки, где все числа расположены в порядке возрастания их величин и совпадают с номерами своих позиций. Например, для n=8 элементов такая лексиграфически наименьшая перестановка имеет следующий вид:
Pmin = (1, 2, 3, 4, 5, 6, 7, 8).
На каждой итерации следующая в лексиграфическом порядке перестановка формируется из текущей перестановки (p1,…,pi,…,pj,…,pn). Пусть, например, на предыдущей итерации была получена перестановка:
Для преобразования ее в очередную перестановку в лексиграфическом порядке необходимо выполнить 3 функциональных действия, которые обеспечивают обратный просмотр элементов, транспозицию элементов и обратную запись хвостовых элементов текущей перестановки.
Сначала путем просмотра текущей перестановки справа налево нужно найти самый правый элемент pi, который меньше своего соседа справа pi+1:
pi < pi+1 | pk > pk+1 при любых k > i.
В данном случае (pi=5)<(pi+1=8). Затем следует найти наименьший элемент pj справа от pi, который больше pi:
В данном случае pj=7. Далее нужно поменять местами pi=5 с pj=7 и перестановка выглядит уже так:
P = (p1, …, pj, pi+1, …, pi, pi+1, …, pn) = (2, 6, 7, 8, 5, 4, 3, 1).
Наконец, хвост
перестановки, начиная с
pi+1=8, необходимо записать в обратном порядке, и в итоге получается лексиграфически следующая перестановка:
Аналогичные итерации требуется продолжать до достижения лексиграфически наибольшей перестановки, где все числа расположены в порядке убывания их величин:
P = (n, n−1, …, 2, 1) = (8, 7, 6, 5, 4, 3, 2, 1).
Рассмотренный лексиграфический алгоритм можно легко приспособить для порождения
перестановок в
обратном лексиграфическом порядке. В таком порядке последовательность перестановок начинается с лексиграфически наибольшей, а каждая следующая перестановка лексиграфически меньше предыдущей. Чтобы получить указанный порядок лексиграфическим алгоритмом, нужно просто инвертировать все знаки отношений сравнения элементов и поиск наименьшего правого элемента везде заменить поиском наибольшего. После такого изменения лексиграфический алгоритм порождает, например, следующую последовательность чисел, где все перестановки цифр
1,
2 и
3 перечислены в обратном лексиграфическому порядке:
ПR: (321) > (312) > (231) > (213) > (132) > (123).
Следует отметить, что в обоих вариантах
лексиграфического порядка сравнение
перестановок производится по первому несовпадающему элементу. Если для сравнения перестановок рассматривать последний несовпадающий элемент, то образуется противоположный порядок
перечисления, который называется
антилексиграфическим. В этом порядке для любой пары соседних перестановок равной длины последний из их несовпадающих элементов у следующей перестановки пары должен быть меньше, чем в предыдущей перестановке.
ПA: (123) < (213) < (132) < (312) < (231) < (321).
Однако имеется специальный рекурсивный алгоритм, который непосредственно генерирует последовательность
перестановок в
антилексиграфическом порядке. В этом алгоритме искомая последовательность перестановок n элементов формируется из блоков уже полученных ранее перестановок
(n−1) элементов, в которые по определенным правилам добавляется элемент
n. Каждый такой блок состоит из
(n−1)! перестановок и всего формируется
n блоков, которые индексируются целыми числами от
n до
1 в следующем порядке:
Bn, …, Bi, …, B1 .
Начальный блок
Bn образуют все уже построенные рекурсивно
перестановки (n−1) элементов, в каждую из которых добавлен справа элемент со значением
n. Каждый следующий блок с номером
i от
(n−1) до
1 должен состоять из
(n−1)! перестановок, в которых последний элемент имеет значение
i. При этом перестановки блока
Bi получаются транспозицией элементов со значениями
i и
(i+1) в перестановках предыдущего блока
Bi+1, где во всех перестановках последний элемент имеет значение
(i+1). Это преобразование блока
Bi+1 в блок
Bi можно записать следующим образом:
Bi+1 = [(p1, … pj=i, … pn=i+1)]i+1 (pj = i <−> pn = i+1) > Bi = [(p1, … pj=i+1, … pn=i)]i.
Указанный процесс преобразований завершает формирование блока
B1, в котором значение последнего элемента для всех
перестановок равно единице. Таким образом, получается антилексиграфическая последовательность
n(n−1)! перестановок из
n элементов. Она может быть использована для рекурсивного построения любых перестановок высших порядков. Рассмотренный алгоритм иллюстрирует следующий пример формирования цифровых перестановок из трех элементов, где каждый блок выделен парой квадратных скобок
[ ], а подчеркивание обозначает добавление и транспозиции элементов в перестановках блоков:
[(12);(2,1)] +3> < [(123);(213)]3 3<−>2 > [(132);(312)]2 2<−>1 > [(231);(321)]1 >.