很多问题都可以暴力解决,不用动太多脑筋,把所有可能性列出来,然后一一试验。尽管这样的方法显得很笨,但却常常是行之有效的。
有没有想过如何打印所有排列呢?输入整数n,按字典序从小到大的顺序输出前n个数的所有排列。前面讲过,两个序列的字典序大小关系等价于从头开始第一个不相同位置处的大小关系。例如,(1,3,2) < (2,1,3),字典序最小的排列是(1,2,3,4,...,n),最大的排列是(n,n-1,n-2,..1).n=3时,所有排列的排序结果是(1,2,3)、(1,3,2,)、(2,1,3)、(2,3,1)、(3,1,2)、(3,2,1)。
生成1-n的排列。
输入:正整数n
输出:1-n的全排列。
运行结果:
我们可以尝试用递归的思想解决:先输出所有以1开头的排列(这一步是递归调用),然后输出以2开头的排列(又是递归调用),接着是以3开头的排列....最后才是以n开头的排列。
以1开头的排列的特点是i:第一位是1,后面是2-9的排列,根据字典序的定义,这些2-9的排列也必须按照字典序排列。换句话说,需要“按照字典序输出2-9”的排列,不过需注意的是,在输出时,每个排列的最前面要加上1,这样一来,所设计的递归函数需要一下参数:
已经确定的前缀序列,以便输出。
需要进行全排列的元素集合,以便依次选做第一个元素。
这样可得到一个伪代码:
void print_permutation(序列A, 集合S)
{
if(S为空)
输出序列A;
else 按照从小到大的顺序依次考虑S的每个元素v
{
print_permuta