Надо упорядочить все перестановки в лексикографическом порядке (имеется в виду запись перестановки как

, где

-й элемент переходит на место

), а потом явно указать правило перехода к следующей перестановке. Правило такое:
Находим ближайшую к концу пару элементов, в котором следующий элемент меньше предыдущего (пусть это пара

), теперь переставляем элементы с

-го по

-ый в таком порядке: на

-е место ставим наименьший элемент, больший

, а остальные располагаем в порядке возрастания.
Начинается перебор перестановок с тождественной, заканчивается перестановкой вида

P.S. Если программируете на C++, то в STL есть функция next_permutation(), которая самостоятельно проделывает все вышеописанное.