Рекурсивно сгенерировать полный массив из n элементов (язык C)

Полный массив вопросов:

Разработайте рекурсивный алгоритм для генерации 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;
}

результат операции:
Результаты запуска полного массива

рекомендация

отblog.csdn.net/diqiudq/article/details/128585342