Полный массив вопросов:
Разработайте рекурсивный алгоритм для генерации nnn элементов{ r 1 , r 2 , ⋯ , rn } \{r_1,r_2,\cdots,r_n\}{ г1,р2,⋯,рн} полная перестановка.
设R знак равно { р 1 , р 2 , ⋯ , rn } R = \ {r_1, r_2, \ cdots, r_n \}р"="{ г1,р2,⋯,рн} - это nn,который нужно упорядочитьn个元素,R i = R - { ri } R_i = R-\{r_i\}ря"="р−{ гя} .коллекцияХХПолная перестановка элементов в X обозначается какperm ( X ) perm(X)p er m ( X ) ,( ri ) perm ( X ) (r_i)perm (X)( ря) per m ( X ) означает perm ( X ) perm(X) в полной перестановкеПерестановка, полученная добавлением префикса к каждой перестановке per m ( X ) .
Например: R = {1, 2, 3} R=\{1,2,3\}р"="{ 1 ,2 ,Полная перестановка 3 } равна{1, 2, 3} \{1,2,3\}{ 1 ,2 ,3 } ,{1, 3, 2} \{1,3,2\}{ 1 ,3 ,2 } ,{ 2 , 1 , 3 } \{2,1,3\}{ 2 ,1 ,3 } ,{ 2 , 3 , 1 } \{2,3,1\}{ 2 ,3 ,1 } ,{3, 2, 1} \{3,2,1\}{ 3 ,2 ,1 } ,{3 , 1 , 2 } \{3,1,2\}{ 3 ,1 ,2 } .
Согласно приведенному выше определению, R = {1, 2, 3} R=\{1,2,3\}р"="{ 1 ,2 ,3 } Чтобы выполнить полную аранжировку, тогдаR 1 = { 2 , 3 } R_1=\{2,3\}р1"="{ 2 ,3 } ,р 2 знак равно { 1 , 3 } R_2 = \ {1,3 \}р2"="{ 1 ,3 } ,р 3 знак равно { 1 , 2 } R_3 = \ {1,2 \}р3"="{ 1 ,2 } , тоperm ( R ) perm(R)за м ( R ) на( r 1 ) доп ( R 1 ) (r_1) доп (R_1 )( р1) на м ( R _1) ,( r 2 ) доп ( R 2 ) (r_2) доп(R_2)( р2) на м ( R _2) ,( r 3 ) доп ( R 3 ) (r_3) доп(R_3)( р3) на м ( R _3) форма. В это время perm ( R 1 ) perm(R_1)может быть получен соответственно тем же методомза м ( R _1) ,перм ( R 2 ) перм (R_2)за м ( R _2) ,перм ( R 3 ) перм (R_3)за м ( R _3) и так далее, чтобы получить всю перманентную завивкув будущемper m , пока каждый запрошенный набор не будет содержать ровно один элемент.
Следовательно, с ннRR из n элементовПолная перестановка R perm ( R ) perm(R)на м ( R ) можно индуктивно определить как :
допуск ( р ) знак равно { ( р ) п знак равно 1 ( р 1 ) допуск ( р 1 ) , ⋯ , ( rn ) допуск ( р п ) п > 1 допуск (R) = \ begin {cases} (r) & n = 1\\ (r_1)разрешение(R_1),\cdots, (r_n)разрешение(R_n)&n>1\\ \end{case}за м ( р ) _"="{ ( р )( р1) на м ( R _1) ,⋯,( рн) на м ( R _н)н"="1н>1
Код реализации:
#include <stdio.h>
void perm(int r[], int head, int rear)
//head是r中所要处理的第一个元素位置,rear是r的末尾元素位置
{
int tmp, i;
if (head == rear)
//递归终止条件:当集合中只有1个元素时
{
for (i = 0; i <= rear; i++) printf("%d ", r[i]);
//输出一种排列方式
printf("\n");
}
else
{
for (i = head; i <= rear; i++)
//从head开始,轮流拿掉一个元素形成新的前缀,并求剩下元素的全排列
{
tmp = r[head]; r[head] = r[i]; r[i] = tmp;
//将第i个元素交换到head位置成为前缀,此时前缀储存在a[0,head],剩下元素储存在r[head+1,rear]
perm(r, head + 1, rear);
tmp = r[head]; r[head] = r[i]; r[i] = tmp;
//需要保持原数组不变,求完剩下元素全排列后把第i个元素换回去
}
}
}
int main()
{
int a[] = {
1, 2, 3};
perm(a, 0, 2);
return 0;
}
результат операции: