再帰的に全配置を実現する


http://www.cnblogs.com/nokiaguy/archive/2008/05/11/1191914.html
参照
    全配列は一つの組の数を一定の順序で並べます.この組の数がn個あれば、全配列数はnです.これです.今は{1,2,3,4,5}を持っています.
例は、全配置の再帰的アルゴリズムをどのように作成するかを示している.
1、まず最後の二つの数を見ます.4、5.それらの全配列は4 5と5 4、つまり4で始まる5の全配列と5で始まる4の全配列である.
一つの数が全部並んでいることがそのものなので、以上の結果が得られます.
2、後の三つの数は3、4、5です.それらは全部3 4、5、4、5、5、4、5の3、5の3、4の4、5の4、5の3の3の6組の数に並べられています.
つまり3で始まると4、5の全配列の組み合わせ、4で始まると3、5で始まると3、4の全配列の組み合わせと、5で始まると3、4の全配列の組み合わせです.
従って、一組の数p={r 1,r 2,r 3,rn}を設定して、全てperm(p)、pn=p-{rn}に配列されていると推測できる.
したがって、perm(p)=r 1 perm(p 1)、r 2 perm(p 2)、r 3 perm(p 3)、…、rnperm(pn)となります.n=1の場合、perm(p)=r 1です.
分かりやすいように、グループ数全体のすべての数をそれぞれ最初の数と交換して、処理後のn-1個数の全配列にします.

#include <stdio.h>  

int n = 0;  

void swap(int *a, int *b) 
{     
    int m;     
    m = *a;     
    *a = *b;     
    *b = m; 
}  
void perm(int list[], int k, int m) 
{     
    int i;     
    if(k > m)     
    {          
        for(i = 0; i <= m; i++)             
            printf("%d ", list[i]);         
        printf("
"); n++; } else { for(i = k; i <= m; i++) { swap(&list[k], &list[i]); perm(list, k + 1, m); swap(&list[k], &list[i]); } } } int main() { int list[] = {1, 2, 3, 4, 5}; perm(list, 0, 4); printf("total:%d
", n); return 0; }