定义:
从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一
个排列。当m=n时所有的排列情况叫全排列。
鄙人不才,只学到了递归的全排列算法,全排列有俩种,一种是按照字典序排列,一种是无序的排列,下面
我们对俩种进行讲解。
无序全排列(1~9):
首先需要定义一个标记,来将需要的换位置,无序全排列主要思想就是回溯。标志到哪里的时候就拿标志后
面的和此位置换,借此来达到全排列的目的。
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int n,cnt=0;
int a[10]={1,2,3,4,5,6,7,8,9};
void fun(int k)//标志
{
if(k==n-1)//当标志到了最后一个的时候就可以输出了 ,因为后面没有可以换的了
{
cnt++;
for(int i=0;i<n;i++)
printf("%d ",a[i]);
printf("\n");
}
else
{
for(int i=k;i<n;i++)
{
swap(a[i],a[k]);//换位置
fun(k+1);//递归
swap(a[i],a[k]);//回溯
}
}
}
int main()
{
cnt=0;
cin >> n;
fun(0);
cout << cnt << endl;
}
字典序全排列:
主要思想是按顺序复制给需要输出的数组,也需要定义一个标记变量来记住需要在哪个位置赋值,用一个数
组来记住哪些数已经被赋值,从小到大遍历,找到未赋值的数赋值给k处即可。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<string>
#include<cstring>
#include<map>
#include<vector>
#include<set>
#include<cmath>
#define ll long long
using namespace std;
int b[11],a[11];
int n;
void fun(int k)
{
if(n==k-1)//此时已经按照字典序复制了n个可以输出了
{
for(int i=1;i<=n;i++)
printf("%d",a[i]);
printf("\n");
}
else
{
for(int i=1;i<=n;i++)//从小到大遍历
{
if(b[i]==0)//没用过的进入
{
b[i]=1;//标记为用过
a[k]=i;//将需要输出的数组第k个赋值
fun(k+1);//递归
b[i]=0;//回溯
}
}
}
}
int main()
{
while(~scanf("%d",&n))
{
memset(b,0,sizeof(b));
fun(1);
}
return 0;
}