比如有一个数组:
int arr[]={1,2,3};
将这个数组里面的元素进行全排列得到下面几组数据:
1,2,3
1,3,2
2,1,3
2,3,1
3,1,2
3,2,1
设R={r1,r2,r3,…,rn}是要进行排列的n个元素,Ri=R-{ri},集合X中元素的全排列记为perm(X)。(ri)perm(X)表示在全排列perm(X)的每一个排列前加上前缀ri得到的排列。
排列过程如下图所示:
主要思想是将问题的规模缩小然后使用递归来解决。
C语言代码:
void Perm(int* ar, int k, int m)
{
if (k == m)
{
for (int i = 0; i <= m; i++)
{
cout << ar[i] << " ";
}
cout << endl;
}
else
{
for (int j = k; j <= m; j++)
{
swap(ar[k], ar[j]);
Perm(ar, k + 1, m);
swap(ar[k], ar[j]);
}
}
}
int main()
{
int ar[] = { 1,2,3 };
int n = sizeof(ar) / sizeof(ar[0]);
Perm(ar, 0, n - 1);
return 0;
}
c++代码:
void Perm(vector<int> &ar, int k, int m)
//ar使用引用减少了构造vector的次数
{
if (k == m)
{
for (auto& x : ar)
{
cout << x << " ";
}
cout << endl;
}
else
{
for (int j = k; j <= m; j++)
{
swap(ar[k], ar[j]);
Perm(ar, k + 1, m);
swap(ar[k], ar[j]);
}
}
}
int main()
{
vector<int> ar = { 1,2,3 };
Perm(ar, 0, ar.size() - 1);
return 0;
}
递归的过程如下所示(只给出了以1打头的过程,其余过程都雷同):
代码运行结果如下所示: