一.什么是全排列?
从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。高中的时候大家一定都知道下面的公式吧!
公式:全排列数f(n)=n!(定义0!=1),如1,2,3三个元素的全排列为:(按照字典序的顺序的话)
1,2,3
1,3,2
2,1,3
2,3,1
3,1,2
3,2,1
共3*2*1=6种。
二.完成全排列的思路和方法
其实对于全排列网上的方法有很多,大多数是传统递归,一步步的得出结果,但是有点难以理解,这里我使用循环+递归的方式,一层一层的出结果,其实思路比其他算法,还是比较简单和理解的。
大家肯定注意到,上面全排列的每一次排列中,都不会出现相同的元素,所以这里的关键的是建立标记数组,并将前面已经存在的相同元素标记为已经存在,这样在进行下一次for循环赋值的时候就不会再将相同的值赋值进入数组的相应位置。这样也能够根据字典序来进行输出排列!
三.全排列的具体实现代码
bool flag[maxa]-----标记数组,已经赋值过的元素,标记为true,假如arry[1]=2,那么后续的arry[2 3 ],都不会再考虑2这个元素了,只会选择还没标记为true的2或者3来进行赋值,后续一直这样,这样就达成了进行全排列的规则。
int generatep(int index)----在index位置进行插入元素。这个数组表示,递归的进行在每个位置进行选择插入没有没标记为true的元素。
#include<stdio.h>
const int maxa=13;//最大值
int arry[maxa]={0};//初始数组
bool flag[maxa]={false};//标记数组
int generatep(int index);//递归插入数组
int n;
int main()
{
n=3;
generatep(1);
return 0;
}
int generatep(int index)
{
if(index==n+1){
for(int i=1;i<=n;i++){//数组从1开始存元素
printf("%d",arry[i]);
}
printf("\n");
}
for(int j=1;j<=n;j++){
if(flag[j]==false){
arry[index]=j;
flag[j]=true;//标记
generatep(index+1);//递归下一个位置
flag[j]=false;//还原
}
}
}
运行结果如下图: