前面我们介绍了全排列的非递归算法,现在我再来写一下全排列的递归算法:
这两种算法的算法思路并不相同。递归算法的思路比较接近于我们现实生活中的思路。
1.试想,我们只有两个数字:12.要对它进行全排列,第一种方式就是12本身,第二种,将12交换,变为21即可。这提示了我们一种交换的思路。
2.但这概括的并不全面。试想,我们要对123进行全排列。我们可以采用将1固定,“23”进行全排列,将“2”固定,对“13”进行全排列。将“3”固定,对“12”进行全排列。
这其实就是首部为”1“,然后是“2”,然后是“3”,不就是第二位后边的数依次和第一位进行交换么?这是典型的递归的思路。
3.但是,这样也不全面,我们每次交换要将排列恢复成为原始的“123”,因为这个算法求排列的时候,前后并没有依赖性,其参考物只有“123”这个原始的第一个排列。否则,如果我们不恢复的话,就会出现,虽然数量与正确解法相同,但是会有重复的排列的现象。
这样,我们不难写出代码:
#include <iostream>
using namespace std;
int total = 0;
//交换函数
void swapArray(int &a,int &b)
{
int temp;
temp = a;
a = b;
b = temp;
}
//递归函数
void fullPermutation(int * fullArray,int start,int end,int number){
//这里,既可以是">=",也可以是">",,应该也可以是"=="
if(start>=end){
for(int i=0;i<number;i++){
cout<<fullArray[i];
}
cout<<endl;
total++;
}
else{
for(int i=start;i<=end;i++){
swapArray(fullArray[start],fullArray[i]);//交换
fullPermutation(fullArray,start+1,end,number);
swapArray(fullArray[start],fullArray[i]);//注意恢复原样
}
}
}
int main()
{
int number;//全排列的长度
cout<<"Number:"<<endl;
cin>>number;
int * fullArray = new int[number];//动态生成全排列的数组
//初始化
for (int i=0;i<number;i++)
{
fullArray[i] = i+1;
}
fullPermutation(fullArray,0,number-1,number);
cout<<"Total = "<<total;
return 0;
}