首先,这个问题涉及的知识点包括:栈和递归调用;
以n=3为例,全排列为:123,132,213,231,312,321。个数为n!,当n值较小时可以使用暴力循环得到结果。当n值较大时,可能会出现超时问题,这时就需要使用递归调用优化。
定义变量n,book数组用来判断当前位置有没有遍历,a数组存放1-9,栈stc存放排列数组,top为栈顶,数组适量开大一些。
int n,book[20];
int a[20];
int stc[20],top;
主函数部分为
int main()
{
memset(book,0,sizeof(book));
scanf("%d",&n);
int i;
for(i=1; i<=n; i++)
a[i-1]=i;
top=0;
dfs(0);
return 0;
}
memset语句用来数组book初始化为0,表示没有遍历,为1时表示遍历过。for循环用于给数组a赋值。
接下来到了整个问题最核心的部分,递归调用,编写函数dfs。
void dfs(int w)//w表示当前位置
{
if(w==n)//如果当前位置等于n,输出stc【】排列。
{
int i;
for(i=0; i<n; i++)
printf("%d",stc[i]);
printf("\n");
return;//输出完毕后返回
}//以下部分是w不等于n时
int i;
for(i=0; i<n; i++)
{
if(book[i]==0)//判断当前位置是否遍历
{
book[i]=1;//没有就进行标记
stc[top++]=a[i];//往stc中输入一个数
dfs(w+1);//位置前进1,递归调用dfs函数
top--;//调用后必须往前回溯,重新进入排列
book[i]=0;//回溯后标记为0,没有遍历。
}
}
}
最主要的部分就是递归函数,理解完递归函数后,这道题就没什么问题了。
完整代码如下:
#include<string.h>
#include<iostream>
using namespace std;
int n,book[20];
int a[20];
int stc[20],top;
void dfs(int w)
{
if(w==n)
{
int i;
for(i=0; i<n; i++)
printf("%d",stc[i]);
printf("\n");
return;
}
int i;
for(i=0; i<n; i++)
{
if(book[i]==0)
{
book[i]=1;
stc[top++]=a[i];
dfs(w+1);
top--;
book[i]=0;
}
}
}
int main()
{
memset(book,0,sizeof(book));
scanf("%d",&n);
int i;
for(i=1; i<=n; i++)
a[i-1]=i;
top=0;
dfs(0);
return 0;
}