#include <iostream>
using namespace std;
void swap(int &a,int &b){
int temp=a;
a=b;
b=temp;
}
void perm(int list[],int low,int high){
if(low==high){ //当low==high时,此时list就是其中一个排列,输出list
for(int i=0;i<=low;i++)
cout<<list[i];
cout<<endl;
}else{
for(int i=low;i<=high;i++){//每个元素与第一个元素交换
swap(list[i],list[low]);
perm(list,low+1,high); //交换后,得到子序列,用函数perm得到子序列的全排列
swap(list[i],list[low]);//最后,将元素交换回来,复原,然后交换另一个元素
}
}
}
int main()
{
int list[]={1,2,3};
perm(list,0,2);
return 0;
}
我们把上面全排列的方法归纳一下,基本上就是:任意选一个数(一般从小到大或者从左到右)打头,对后面的n-1个数进行全排列。聪明的读者应该已经发现,这是一个递归的方法,因为要得到n-1个数的全排列,我们又要先去得到n-2个数的全排列,而出口是只有1个数的全排列,因为它只有1种,为它的本身。写成比较规范的流程:
1.开始for循环。
2.改变第一个元素为原始数组的第一个元素(什么都没做)。
3.求第2个元素到第n个元素的全排列。
4.要求第2个元素到第n个元素的全排列,要递归的求第3个元素到第n个元素的全排列。......
5.直到递归到第n个元素到第n元素的全排列,递归出口。
6.将改变的数组变回。
7.改变第一个元素为原始数组的第二个元素。
(注:理论上来说第二次排列时才改变了第一个元素,即第6步应该此时才开始执行,但由于多执行一次无义的交换影响不大,而这样使得算法没有特殊情况,更容易读懂,如果一定要省时间可以把这步写在此处,这种算法我在下文中便不给出了,读者可以自己写。)5.求第2个元素到第n个元素的全排列。
6.要求第2个元素到第n个元素的全排列,要递归的求第3个元素到第n个元素的全排列。......
5.直到递归到第n个元素到第n元素的全排列,递归出口。6.将改变的数组变回。......
8.不断地改变第一个元素,直至n次使for循环中止。