全排列的递归解法

算法思想:
假定有一个数组,int[] = {1,2,3,4,5};
1.先看数组的最后两个元素:{4,5},它的全排列即是45,54.
2.再看数组的最后三个元素:{3,4,5},它的全排列即是345,354,435,453,534,543.
3.N个元素S = {r1,r2,r3,...,r(n-1),rn}的全排列即是
r1P(S-r1),r2P(S-r2),r3P(S-r3),...,rnP(S-rn);此处P(S-r1)为S数组过滤掉r1后的全排列.
4.依次将待排列的数组的后N-1个元素与第一个元素交换,则每次递归处理的都是后N-1个元素的全排列.当数组元素仅有一个时为此递归算法的出口.

 1 /*
 2 *算法思想:简单地说:就是第一个数分别以后面的数进行交换
 3 *E.g:E = (a , b , c),则 prem(E)= a.perm(b,c)+ b.perm(a,c)+ c.perm(a,b)
 4 *然后a.perm(b,c)= ab.perm(c)+ ac.perm(b)= abc + acb.依次递归进行。
 5 *去掉重复符号的全排列:在交换之前可以先判断两个符号是否相同,不相同才交换,
 6 *这个时候需要一个判断符号是否相同的函数。
 7 */
 8 #include <iostream>
 9 #include <algorithm>
10 using namespace std;
11 int cnt = 1;    //记录排列的个数
12 
13 bool isSwap(int p[],int nBegin, int nEnd)
14 {
15     for(int i = nBegin; i < nEnd; i++)
16     {
17         if(p[i] == p[nEnd])
18             return false;
19     }
20     return true;
21 }
22 
23 //start 表示当前的数,n表示数组中数的个数
24 void   permutation(int p[],int cur,int n)
25 {
26     if(cur == n-1)
27     {
28         cout<<""<<cnt++<<"个全排列: ";
29         for(int i = 0; i < n; i++)
30             cout<<p[i];
31         cout<<endl;
32     }
33     else
34     {
35         for(int i = cur; i <= n-1; i ++)       //第i个数分别与它后面的数字交换就能得到新的排列
36         {
37             if(isSwap(p,cur,i))                  //判断是否相等,中间是相等的元素则不需交换
38             {
39                 swap(p[cur],p[i]);
40                 permutation(p,cur+1,n);
41                 swap(p[cur],p[i]);
42             }
43         }
44     }
45 }
46 
47 int main()
48 {
49     int p[] = {1,2,2,4};
50     permutation(p,0,4);
51 
52     return 0;
53 }
54 
55  

 

posted @ 2016-02-03 18:00  Gladitor  阅读(1670)  评论(0编辑  收藏  举报