
- •1Введение
- •2Сортировки
- •2.1Сортировки массивов
- •2.2Сортировка простым включением
- •2.3Сортировка простым выбором
- •2.4Сортировка простым обменом
- •2.5Сравнение простых сортировок
- •2.6 Сортировка шелла
- •2.7Пирамидальная сортировка
- •2.8Быстрая сортировка
- •2.9Поиск медианы и квантилей
- •2.10Сравнение сортировок
- •3Поиск подстроки в строке
- •3.1Поиск в строке
- •3.2Простой поиск в строке
- •3.3Поиск в строке. Алгоритм боуера-мура
- •4Генерация перестановок
- •4.1Генерация перестановок последовательности натуральных чисел
- •4.2Генерация перестановок элементов в антилексикографическом порядке
- •4.3Генерация перестановок за одну транспозицию элементов
- •4.4Генерация перестановок за одну транспозицию соседних элементов
- •5Генерация подмножеств
- •5.1Генерация всех подмножеств множества
- •5.2Генерация m -элементных подмножеств множества натуральных чисел
- •Var m: integer; {Размер подмножества}
- •Var I, j, p: integer;
- •5.3Генрация k-компонентных выборок на множестве {0, 1}
- •Var k: integer; {Количество нулей в кортеже}
- •I: integer;
- •Var I, j, p: integer;
- •If Finish then Break {Exit};
- •6Генерация разбиений
- •6.1Разбиение целых чисел
- •Var I, j: integer;
- •Var j: integer;
- •Var I, j, k: integer;
- •Var d, l, Sum: integer;
- •6.2Разбиение множеств
- •/1, 2, 3/ И /4/ затем /1, 2/ и /3, 4/ и т.Д. }
- •I, j, k, r, s: integer;
- •If not Flag2 then
- •If Flag1 then
- •If Forvd[j] then { j движется вперед}
- •7Обходы бинарных деревьев
- •7.1Процедуры прохождения бинарных деревьев
- •8Поиск на бинарных деревьях
- •8.1Процедуры поиска на бинарных деревьях
- •Рекомендованная литература
4.3Генерация перестановок за одну транспозицию элементов
Алгоритм генерирования перестановок, требующий одну транспозицию для получения очередной перестановки, реализуется рекурсивным образом с помощью процедуры Perm, содержащей один параметр - количество первых элементов массива P, для которых выполняется перестановка.
Пусть массив P, содержит последовательность вида:
P[1] |
P[2] |
P[3] |
|
P[m-3] |
P[m-2] |
P[m-1] |
P[m] |
a1 |
a2 |
a3 |
|
am-3 |
am-2 |
am-1 |
am |
Задачей процедуры Perm(n) является генерирование всех перестановок элементов
P[1], …, P[n]
через последовательное генерирование блока всех перестановок элементов
P[1], …, P[n-1]
при фиксированном элементе P[n] с последующей транспозицией элемента P[n] и одного из элементов
P[1], …, P[n‑1]
Пусть необходимо сгенерировать блок перестановок из m<=n элементов. При заданном P[m] генерируется блок перестановок из (m-1)! перестановок элементов P[1], …, P[m-1]. После этого определяется элемент из P[1], …, P[m-1], для которого выполняется транспозиция с элементом P[m].
Пусть задана последовательность 1, 2, 3, 4 и следующий набор перестановок для этой последовательности. Для каждой перестановки в этой последовательности выделена пара элементов, которые подвергаются транспозиции на каждом шаге генерации очередной перестановки.
1 2 3 4
2 1 3 4
2 3 1 4
3 2 1 4
3 1 2 4
1 3 2 4
4 3 2 1
3 4 2 1
3 2 4 1
2 3 4 1
2 4 3 1
4 2 3 1
4 1 3 2
1 4 3 2
1 3 4 2
3 1 4 2
3 4 1 2
4 3 1 2
(Обратить внимание на перестановку элементов 2 и 3)
4 2 1 3
2 4 1 3
2 1 4 3
1 2 4 3
1 4 2 3
4 1 2 3
На основе анализа приведенного примера можно предложить алгоритм выбора элемента из
P[1], …, P[m-1]
для которого выполняется транспозиция с элементом P[m]. Этот алгоритм позволяет находить соответствующий индекс B(m, i), где P[B(m, i)] {P[1], …, P[m‑1]} и 1 <= i < m <= n.
В работе алгоритма различаются два случая, когда m – длина блока, четно и нечетно:
если m - нечетно, то после генерации очередного блока из (m-1)! перестановок для каждого i, 1 =< i <= m-1, выполняется перестановка P[B(m, i)] и P[m], где B(m, i) = m-1.
если m - четно, то, после генерации очередного блока из (m-1)! перестановок, для каждого i, 1 =< i <= m-1, выполняется перестановка P[B(m, i)] и P[m], где B(m, i) = i. Таким образом, содержимое P[m] последовательно меняется с содержимым P[1], P[2], …, P[m-2], P[m-1] (исключение составляет случай i = m-1 см. пример)
Процедура B имеет вид:
function B (M, I: integer): integer;
begin
if (M mod 2 = 0) and (M > 2) then
if I < M-1 then B := I
else B := M –2 {см. пример отмеченный случай перестановки элементов 2 и3}
else B := M-1;
end; {B}
Рассмотрим суть алгоритма генерации перестановок. Пусть элементы массива P образуют возрастающую последовательность натуральных чисел, т. е. P[i] = ai = i, где 1<=i<=m. Через ai обозначим элемент массива P[i].
Пусть m нечетно. Очередной вызов процедуры Perm(m-1), т. е. m-1 – четно, фактически выполняет циклический сдвиг на одну позицию в право последовательности P[1], P[2], …, P[m-2], P[m‑1] (см. случай, когда m четно). После вызова этой процедуры выполняется транспозиция элементов P[m] и P[m‑1]. В результате для каждого i, 1 =< i <= m-1, вызов процедуры Perm(m-1) в P[m] последовательно размещаются значения элементов
am, am-2, am-3, …, a2, a1, am-1
Бросается в глаза, что элемент am-1 попадет в позицию P[m] последним. Это следствие того, что сдвиг элементов массива выполняется до транспозиции элементов P[m] и P[m‑1]. Например, если массив содержит последовательность 1, 2, 3, 4, 5, то после первого вызова (i=1) процедуры Perm(5) эта последовательность изменится на 4, 1, 2, 5, 3.
Пусть m четно. Очередной вызов процедуры Perm(m-1) выполняет транспозицию элементов P[m] и P[i], для каждого i, 1 =< i <= m-1. Например, если массив содержит последовательность 1, 2, 3, 4, то после первого вызова (i=1) процедуры Perm(4) эта последовательность изменится на 4, 1, 2, 3.
Программа, реализующая данный алгоритм, имеет вид:
program Permutation3;
uses crt;
const N = 4;
var
I: integer;
Arr: array [1..N] of integer;
function B (M, I: integer): integer;
begin
if (M mod 2 = 0) and (M > 2) then
if I < M-1 then B := I
else B := M –2 {см. пример отмеченный случай перестановки элементов 2 и3}
else B := M-1;
end; {B}
procedure Perm (M: integer);
var I, J, Work: integer;
begin
if M = 1 then
begin
for J := 1 to N do Write (Arr[J], ' ');
Writeln;
end
else
for I := 1 to M do
begin
Perm (M-1);
if I < M then
begin
Work := Arr[B(M, I)];
Arr[B(M, I)] := Arr[M];
Arr[M] := Work;
end;
end;
end; {Perm}
begin
Clrscr;
for I := 1 to N do Arr [I] := I;
Perm (N);
end. { Permutation3}