n 要素の完全な配列を再帰的に生成します (C 言語)

完全な配列の質問:

nnを生成する再帰的アルゴリズムを設計するn要素{ r 1 , r 2 , ⋯ , rn } \{r_1,r_2,\cdots,r_n\}{ r1r2r}完全な置換。

R = { r 1 , r 2 , ⋯ , rn } R=\{r_1,r_2,\cdots,r_n\}R={ r1r2r}は配置されるnnn個の元素、R i = R − { ri } R_i=R-\{r_i\}R私は=R{ r私は.コレクションXXX内の要素の完全な順列はperm ( X ) perm(X)として表されます。perm ( X ) ,( ri ) perm ( X ) (r_i)perm( X )( r私は) per m ( X )は、完全な順列perm ( X ) perm(X)per m ( X )の各順列に接頭辞を追加することによって得られる順列

例: R = { 1 , 2 , 3 } R=\{1,2,3\}R={ 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\}R={ 1 2 3 }フルアレンジメントを実行するには、R 1 = { 2 , 3 } R_1=\{2,3\} となります。R1={ 2 3 } ,R 2 = { 1 , 3 } R_2=\{1,3\}R2={ 1 3 } ,R 3 = { 1 , 2 } R_3=\{1,2\}R3={ 1 2 }、次にperm ( R ) perm(R)per m ( R ) by( r 1 ) perm ( R 1 ) (r_1)perm(R_1 )( r1)パーマ( R _ _1) ,( r 2 ) パーマ ( R 2 ) (r_2) パーマ(R_2)( r2)パーマ( R _ _2) ,( r 3 ) パーマ ( R 3 ) (r_3) パーマ(R_3)( r3)パーマ( R _ _3フォーム。このとき、 perm(R 1 ) perm(R_1) も同様の方法でそれぞれ求めることができます。パーマR _ _1)パーマ ( R 2 ) パーマ(R_2)パーマR _ _2)パーマ ( R 3 ) パーマ(R_3)パーマR _ _3 、など将来的にパーマを要求された各セットに 1 つの要素が含まれるまでmごとに。

したがって、nnではn個の要素RRRの完全な順列perm ( R ) perm(R)per m ( R )は帰納的に次のように定義できます

perm ( R ) = { ( r ) n = 1 ( r 1 ) perm ( R 1 ) , ⋯ , ( rn ) perm ( R n ) n > 1 perm(R)=\begin{cases} (r)&n= 1\\ (r_1)perm(R_1),\cdots, (r_n)perm(R_n)&n>1\\ \end{cases}パーマ( R ) _ _={ ( r )( r1)パーマ( R _ _1( r)パーマ( R _ _)n=1n>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
おすすめ