全排列算法
全排列算法:
#include<iostream>
using namespace std;
template <class Type>
void Perm(Type list[], int k, int m)
{
if(k==m)
{
for(int i=0; i<=m; i++)
cout << list[i];
cout << endl;
}
else
for(int j=k; j<=m; j++)
{
Swap(list[k],list[j]);
Perm(list, k+1, m);
Swap(list[k],list[j]);
}
}
template<class Type>
inline void Swap(Type &a, Type &b)
{
Type temp=a;
a=b;
b=temp;
}
这是经典的全排列算法。m和k分别表示要进行全排列的元素范围,即两个端点的index,m为开始的index,k为结束端点index。
template <class Type>
//k和m表示需要被全排列的元素范围--两端点的index
void Perm(Type list[], int k, int m)
{
if(k==m) //被处理的范围缩小为0
{
for(int i=0; i<=m; i++)
cout << list[i];
cout << endl;
}
else
for(int j=k; j<=m; j++)
{
Swap(list[k],list[j]);//下标为k和j的元素交换在数组中的位置
Perm(list, k+1, m););/*每次调用时k+1,即全排列范围缩小1*/
Swap(list[k],list[j]);//回溯的时候,还原为先前状态
}
}
给你讲讲算法思想吧:
假设我们求permute(abc)的全排列。permute(abc)的全排列=a+permute(bc)和b+permute(ac)和c+permute(ab)=…………….依次类推。所以就可以用递归做。而将abc拆分成a+bc,b+ac,c+ab的过程就是上面的:
for(int j=k; j<=m; j++)
{
Swap(list[k],list[j]);
Perm(list, k+1, m);
Swap(list[k],list[j]);
}
这个过程。做好以后还要换回来,恢复原状,接着做。
当最后只有1个字母的时候,即k=m的时候,只有一种情况,因而输出。