递归全排列(最细教学兄弟们)------走过路过不要错过!!!!!

首先,组长要求,被迫营业(吐槽一下)

选这题呢,是因为我觉得很有意思😎,还有就是好多同学没有写,分享一下在网上学到的一个很有意思的做法

终于,步入正题

L1-2【用递归实现】 输出全排列 (20 分)
 

请编写程序输出前n个正整数的全排列(n<10),并通过9个测试用例(即n从1到9)观察n逐步增大时程序的运行时间。

输入格式:

输入给出正整数n(<10)。

输出格式:

输出1到n的全排列。每种排列占一行,数字间无空格。排列的输出顺序为字典序,即序列a1,a2,,an排在序列b1,b2,,bn之前,如果存在k使得a1=b1,,ak=bk 并且 ak+1<bk+1

输入样例:

3
 
结尾无空行

输出样例:

123
132
213
231
312
321
 
结尾无空行
 
 
 
首先题目给出的案例3
看他的输出样例,你会发现,123和132,是后面两个数换了个位置,然后进入2开头的排序,这就很符合递归的思想
因为掌握了输出规律
首先定义这个函数
void paixu(int step)  //没啥英语底子母语跟上
所以我们可以直接进行输出,无需记入,但需要int一个一个数组来记入几个数字,因为要修改吗,所以在这几个数组里有没有数组就需要确认一下
因为题目n<=10嘛
所以直接int a[11],int flag[11]
规定一个step来计入有几个数字,满n个以后就可以输出
所以先int step=0;
if(step == n+1){
for(int i=1;i<=n;i++){
  cout << a[i] ;
}
  cout << endl;//因为很懒而且题目没要求就多一行吧
}
输出结构确认了就可以考虑递归内容啦
step不等于1嘛
else{
  for(int i=1;i<= n;i++){  //这个for循环就很精妙,就是靠这个for进行重置
  if(flag[i]==0){  
  flag[i]=1;  //记入数字嘛,有数字你就可以变成1了
  a[step]=i;  //注意这里是给step赋值,因为最终是靠step来判断是否输出
  paixu(step+1);  //给他赋值完,就去找下一个目标啦
  flag[i]=0;  //这个步骤就是重新排序的关键步
}
}
}
单单一点代码没那么好理解我知道,
来跟着思路走一波
3太简单了,所以我们按4来举例
------------------------------------------------------

1234
1243
1324
1342
1423
1432
2134
2143
2314
2341
2413
2431
3124
3142
3214
3241
3412
3421
4123
4132
4213
4231
4312
4321

------------------------------------------------------------------

看这段案例不难发现

1234,先解放3,改为1243,

再解放2,排入3,按顺序变成1324

聪明的你们应该就可以看懂啦

(1)1234

step=1,进入for循环,定义a[1]=1,step++  //这里函数没有结束,i=1差一步,而且2,3,4的for循环没开始哦!!!!!

step=2,进入for循环,因为i=1的时候,flag[1]==1了,所以进入i=2的循环,给a[2]赋值  //3,4没进行

step=3,进入for循环,下面都一样  //4没进行

step=4,还是一样,但是step+1=5了

step=5,不进入for了,进入输出

数组上所有的数都有定义

成功输出1234

这是会直接结束step=5的函数,所以不会堆积栈太多

(2)1243

这是可不是从step=1重新开始

step=5,结束后,进入step=4,

step=4,flag[4]=0,结束了这个step=4的函数!!!!!  //又少了一个哦

step=3,flag[3]=0,结束了这个for ,i=3,进入i=4,这个时候(-------step=3---------)哦,这部很重要,所以a[step]=i;这一步是a[4]=3,进入step=4

step=4,记住flag[3]=0,所以a[step]=i,这步是a[4]=3,这时所有的数都有值了,可以进入step=5了

step=5,再次输出

(3)1324

同理啦,

 

 

----------------

这个做法不会堆积栈,最多5个,学会这个的时候我超激动得嘞,

一些东西用的不好,见谅哈,但是这个教学绝对系

同学们点个赞呗,写了超久!!!!!!

最后是完整的代码,也给你们啦

#include<stdio.h>
int a[11],flag[11];
int n;
void flo(int step){
    if(step==n+1){
        for(int i=1;i<=n;i++){
            printf("%d",a[i]);
        }
        printf("\n");
    }else{
        for(int i=1;i<=n;i++){
            if(flag[i]==0){
                flag[i]=1;
                a[step]=i;
                flo(step+1);
                flag[i]=0;
            }
        }
    }
}
int main(){
    scanf("%d",&n);
    flo(1);
} 

 

posted @ 2021-10-31 20:19  星落化尘丶  阅读(177)  评论(3编辑  收藏  举报