要求:求1-N的全排列
问题描述
//求多个数字的全部排列方式称为全排列
#include<stdio.h>
int n,i;
void dfs(int step,int*nums,int *ans,int*nums_state,int n){//n记录搜索深度的同时也用来当作答案数组的下标
//int i;//??看起来毫无作用但是删掉后输出就会只剩一行?
if(step==n){ //递推边界
for(i=0;i<n;i++){
printf("%d",ans[i]);
}
printf("\n");
return ;
}
//递推关系式
for(i=0;i<n;i++){
if(nums_state[i]==0){//查找未锁定的数字
ans[step]=nums[i]; //将未锁定的数字放进数组
nums_state[i]=1; //将数字锁定
dfs(step+1,nums,ans,nums_state,n);
nums_state[i]=0; //数字解锁,回溯
}
}
}
int main(){
scanf("%d",&n);
//这里用三个数组更加通用,条件允许可以用hash代替nums和nums_state
int nums[n],ans[n],nums_state[n];//nums数组存储全排列的数字,ans数组记录答案,nums_state数组记录nums数组中数字的状态
for(i=0;i<n;i++){//数组初始化
nums[i]=i+1;
ans[i]=0;
nums_state[i]=0;
}
dfs(0,nums,ans,nums_state,n);
return 0;
}
当注释掉 int i;后输出只剩一行:
当int i;没有注释掉时:
原因分析:
经单步调试发现,当int i;没有注释掉时,递归使用的变量i是自身定义的局部变量i,局部变量只作用于递归,而且递归中的每层之间的i都不会相互影响,当 int i;注释掉后,递归使用的是全局变量,这样造成的后果就是递归每一层的i都会跟全局变量i一起增大,无法实现回溯功能,自然只能输出一行。
经验总结:
回溯不要用全局变量!!!
以及
一个看起来十分离谱的bug,可能是由于小细节的疏忽再加上对知识的理解不到位引起的