#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循环中止。