全排列的算法思想和实现(C++版)
http://www.itmian4.com/forum.php?mod=viewthread&tid=3323
所谓全排列,就是将集合中元素的所有排列情况依次输出。比如{1、2、3}的全排列为:123、132、213、231、312、321,共6种,满足计算公式N!(N为集合中元素个数,不重复)。
当元素不重复时,全排列采用递归思想较容易实现,它的递归公式推导步骤类似:
1、要求得123的全排列,只需求得:1并上23的全排列(1 23, 1 32),2并上13的全排列(2 13, 2 31),3并上12的全排列(3 12 321)。
2、对于23的全排列,只需求得2并上3的全排列,3并上2的全排列。步骤1中13、12的全排列也类似。
3、对于3的全排列或者2的全排列,就是它们的本身。递归结束。
递归实现不重复元素全排列算法的实现代码(C++)如下:
//交换a和b
void Swap(int *a, int *b)
{
int t = *a;
*a = *b;
*b = t;
}
//全排列函数。list:待排元素列表,start:起始位置下标,end:最后一个有效元素的下一个下标。
void Permutation(int start, int end, int list[])
{
int i;
if (start >= end) //递归结束,打印当前这次全排列结果,返回。
{
for (i = 0; i < end; i++)
{
printf("%d ", list[i]);
}
printf("\n");
return;
}
//对于给定的list[start...end],要使区间中每一个元素都有放在第一位的机会,
//然后开始递归调用自身,得到list[start+1...end]的全排列。
for (i = start; i < end; i++)
{
Swap(&list[i], &list[start]); //交换元素,使每一个元素都有放在第一位的机会。
Permutation(start+1, end, list); //递归调用
Swap(&list[i], &list[start]); //恢复原始的list,不影响下次递归调用。
}
}
#include <iostream>
using namespace std;
int main()
{
int a[] = {1, 2, 3};
Permutation(0, 2, a);
return 0;
}