递归全排列(最细教学兄弟们)------走过路过不要错过!!!!!
首先,组长要求,被迫营业(吐槽一下)
选这题呢,是因为我觉得很有意思😎,还有就是好多同学没有写,分享一下在网上学到的一个很有意思的做法
终于,步入正题
请编写程序输出前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
for(int i=1;i<=n;i++){
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); }