什么是数的全排列呢?这里举个例子:123的全排列是123,132,213,231,312,321。
那么接下来,我们用程序来实现输出1~n的全排列。
解决思路1:使用枚举法,尝试所有的可能性
源代码:
#include <stdio.h>
#include <stdlib.h>
#define N 100
int a[N];
int n = 4;
int m;
int sum = 0;
int book[N] = {0};
void fun(int k)
{
for(int i = 1; i <= n; i++)
{
a[k] = i;
if(k != 1)
fun(k - 1);
else
{
for(int j = 1; j <= n; j++)
{
book[j] = 0;
}
for(int j = 1; j <= n; j++)
{
book[a[j]] = 1;
}
sum = 0;
for(int j = 1; j <= n; j++)
{
sum += book[j];
}
if(sum == n)
{
//for(int j = 1; j <= n; j++)
//printf("%d ", a[j]);
// printf("\n");
m++;
}
}
}
}
int main(int argc, char* argv[])
{
n = atoi(argv[1]);
fun(n);
printf("%d\n", m);
return 0;
}
解决思路2:使用深度优先搜索,避免无效的组合
源代码:
#include <stdio.h>
#include <stdlib.h>
#define N 100
int a[N];
int n = 4;
int m;
int sum = 0;
int book[N] = {0};
void fun(int k)
{
int temp;
for(int i = 1; i <= n; i++)
{
if(book[i] != 1)
{
temp = a[k];
if (temp != 0)//如果是第一次,则不需清除原来的标记,若不是,则需要清除原来的标记。
book[a[k]] = 0;
a[k] = i;
book[i] = 1;
}
else
continue;
if(k != 1)
fun(k - 1);
else
{
//for(int j = 1; j <= n; j++)
//printf("%d ", a[j]);
//printf("\n");
m++;
}
}
//清除最后一次的标记。
book[a[k]] = 0;
//这一轮结束,要把数字也清零
a[k] = 0;
}
int main(int argc, char* argv[])
{
n = atoi(argv[1]);
fun(n);
printf("%d\n", m);
return 0;
}
下面是两种算法的执行结果(这里我注释掉了所有情况的输出):
从上面截图可以很清楚看出来,两个算法差距非常大。