一般把1~n这n个整数按某个顺序摆放的结果称为这n个整数的一个排列,而全排列指这n个整数能形成的所有排列。现在需要按字典序从小到大输出1 ~ n的全排列。
从递归的角度去考虑,把它可以分为若干个子问题:
输出以1开头的全排列
输出以2开头的全排列
输出以3开头的全排列
…
于是设一个数组p,用来存放当前的排列,再设定一个散列数组hashTable,其中hashTable[x]当整数x已经在数组p中时为true。
假设当前已经填好了p[1] ~ p[k-1],准备填p[k]。需要枚举1~n,如果当前枚举的数字x还没有在p[1] ~ p[k-1]中,即hashTable[x]==false,那么就把他填入p[k],同时将hashTable[x]=true,然后处理p[k+1]——进入递归,当递归完成时,再将hashTable[x]还原为false,以便让p[k]填下一个数字。
递归边界:当index达到n+1时,说明p的1 ~ n已经填好了,可以输出p数组。
#include<cstdio>
const int maxn = 11;
int n,p[maxn], hashTable[maxn] = {0};
void permutation(int index)
{
if(index==n+1)
{
for (int i = 1; i <= n;i++)
printf("%d", p[i]);
printf("\n");
return;
}
for (int x = 1; x <= n;x++)
{
//如果x不在p[0]~p[index-1]中
if(hashTable[x]==0)
{
//令p的第index位为x,把x加入当前排列
p[index] = x;
//记x已经在p中
hashTable[x] = 1;
//下一层递归
permutation(index + 1);
//处理完p[index]为x的子问题,还原状态
hashTable[x] = 0;
}
}
}
int main()
{
n = 4;
permutation(1);
return 0;
}
如图所示,一小部分递归树,画的太丑了,欢迎指正。