生成排列的递归方法

一  提议描述:

输入正整数n,按照字典序从小到大的顺序输出前n个数的所有排列。

二 思路分析:

对此问题用递归的思想解决:先输出所有以1开头的排列(递归调用),然后输出以2开头的排列(递归调用),接着以3开头的排列,„,最后才是以n开头的排列。 

1开头的排列的特点是:第一位是1,后面是按字典序的29的排列。所以在设计递归函数需要以下参数: 

1)已经确定的“前缀”序列,以便输出; 

2)需要进行全排列的元素集合,以便依次选做第一个元素。 这样,写出以下的伪代码: 

 void print_permutation(序列A,集合S) 

     if(S为空)    输出序列A; 

     else 按照从小到大顺序依次考虑S的每个元素v    

    { 

       print_permutation(A的末尾填加v后得到的新序列,S-{v}); 

     }

 } 

上面的递归函数中递归边界是S为空的情形,可以直接输出序列A;若S不为空,则按从小到大的顺序考虑S中的每个元素,每次递归调用以A开头。 

下面考虑程序的实现。用数组表示序列A,集合S可以由序列A完全确定——A中没有出现的元素都可以选。C语言中的函数在接受数组参数时无法得到数组的元素个数,所以需要传一个已经填好的位置个数,或者当前需要确定的元素位置cur。声明一个足够大的数组A,然后调用print_permutation(n,A,0),即可按字典序输出1n的所有排列。 

 

AC代码:

 

 1 #include<iostream>
 2 using namespace std;
 3 int s[100];
 4 void order(int n,int *a,int cur)
 5 {
 6     if(cur==n)
 7     {for(int i=0;i<n;i++)
 8     cout<<a[i];
 9     cout<<endl;}
10     else
11     {
12         for(int i=1;i<=n;i++)
13         {
14             int ok=1;
15             for(int j=0;j<cur;j++)//寻找在已经排好的序列里面是否有等于i的数字
16             if(a[j]==i) ok=0;
17             if(ok)//没有则把数字引入到数组中
18             {
19                 a[cur]=i;
20                 order(n,a,cur+1);//如果找到则进入下一层递归
21             }  
22         }
23     }
24 }
25 int main()
26 {
27     int n;
28     cin>>n;
29     order(n,s,0);
30     return 0;
31 }

 

 

原文地址:https://www.cnblogs.com/khbcsu/p/3865707.html