一、
全排列算法是一种经典的递归算法。例如集合{1,2,3}的全排列为{(1,2,3)、(1,3,2)、(2,1,3)、(2,3,1)、(3,2,1)、(3,1,2)}共3!种。
递归法求解的思路是先固定第一个元素,求剩下的全排列,求剩下的全拍列时,固定剩余元素中的第一个元素,再求剩下元素的全排列,直到就剩一个元素停止。
例如求集合{1,2,3,4}的全排列。
1、固定元素1求{2,3,4}元素的全排列
(1)、固定元素2求{3,4}的全排列
1)、固定元素3 ,得到一个排列方式(1,2,3,4)
2)、固定元素4,得到一种排列方式(1,2,4,3)
(2)、固定元素3、求{2,4}的全排列
1)、固定元素2,得到一个排列方式(1,3,2,4)
2)、固定元素4,得到一种排列方式(1,3,4,2)
(3)、固定元素4求{2,3}的全排列
1)、固定元素2,得到一个排列方式(1,4,2,3)
2)、固定元素3,得到一种排列方式(1,4,3,2)
经过上述步骤即可得到以1为第一个元素的全排列,再分别将2,3,4固定为第一元素重复上面过程即可得到{1,2,3,4}的全排列
代码如下:
#include<iostream>
using namespace std;
void Swap(int &a,int &b)//交换函数
{
int tmp = a;
a = b;
b = tmp;
}
void Perm(int *br,int k,int m)//递归函数
{
if(k ==m)
{
for(int i = 0; i <= m; ++i)
{
cout<<br[i]<<" ";
}
cout<<endl;
}
else
{
for(int j = k;j<=m;++j)
{
Swap(br[j],br[k]);
Perm(br,k+1,m);
Swap(br[j],br[k]);
}
}
}
int main()
{
int ar[] = {1,2,3,4};
int n = sizeof(ar)/sizeof(ar[0]);
Perm(ar,0,n-1);
return 0;
}
结果:
二、子集排列(递归)
下标全置为0,左孩子为1,右孩子为0,若下标为1,表示输出该位置的值,为0不输出。
代码:
#include<iostream>
using namespace std;
void fun(int *ar,int *br,int i,int n)
{
if(i >= n)
{
for(int j = 0;j < n; ++j)
{
if(br[j])
{
cout<<ar[j]<<" ";
}
}
cout<<endl;
}
else
{
br[i] = 1;
fun(ar,br,i+1,n); //leftchild
br[i] = 0;
fun(ar,br,i+1,n); //rightchild
}
}
int main()
{
int ar[] = {1,2,3};
int br[] = {0,0,0};
fun(ar,br,0,3);
return 0;
}
结果: