全排列问题

全排列问题:

求n个元素的全排列,n个元素中允许出现重复元素,通过实例验证算法。

思路:

设R={r1,r2,…,rn}是要进行排列的n个元素,Ri=R-{ri}。集合X中元素的全排列记为Perm(X)。(ri)Perm(X)表示在全排列Perm(X)的每一个排列前加上前缀ri得到的排列。R的全排列可归纳定义如下:

当n=1时,Perm(R)=(r),其中r是集合R中唯一的元素;

当n>1时,Perm(R)由(r1)Perm(R1),(r2)Perm(R2),…,(rn)Perm(Rn)构成。

       算法Perm(list,k,m)递归地产生所有前缀是list[0:k-1],且后缀是list[k:m]的全排列的所有排列。函数调用Perm(list,0,n-1)则产生list[0:n-1]的全排列。

    在一般情况下,k<m。算法将list[k:m]中的每一个元素分别与list[k ]中的元素交换。然后递归地计算list[k+1:m]的全排列,并将计算结果作为list[0:k]的后缀算法中IsSwap()是用于交换两个变量值的内联函数。

算法实现:

#include
using namespace std;
template
bool IsSwap(Type list[], Type nBegin, Type nEnd) {


	for (int i = nBegin; i < nEnd; i++)

		if (list[i] == list[nEnd])

			return false;

	return true;


}
template
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 i = k; i <= m; i++) {
			if (IsSwap(list,k,i)){
				swap(list[k], list[i]);
					perm(list, k + 1, m);
					swap(list[k], list[i]);
			}
		}
	}
}


template
bool swap(Type &a, Type &b) {
	Type temp = a;
	a = b;
	b = a;
	return true;
}
int main() {
	int arr[] = { 1,1,2 };
	perm(arr,0,2);
	system("pause");
}

运行结果:

全排列问题_第1张图片

你可能感兴趣的:(开发语言,c++,算法)