排列算法
原创、转载请注明出处
1、生成1~n的所有排列,例如(输入n):
代码在底部,思路可参考http://www.cnblogs.com/mu-ye/p/7650871.html
2、生成1~n中元素的排列,排列元素可重复(输入n):
3、P[]中有重复的元素(输入n和P[]):(注意区别于把1、2中的数当作键值的P[])
相对于1,这里元素不可重复的规则不可用。
记录A[](已经排好的元素)中元素的个数和该元素在P[]中的个数,如果A[i]<P[i]就调用函数。
P中相同元素不重复调用函数。
4、C++的STL中有求下一个排列的库函数next_permutation。
枚举排列的常见方法有2种:一是递归枚举,二是用STL中的next_pernutation。
1、
#include<iostream>
using std::cin;
using std::cout;
using std::endl;
void f(int A[], int cur, int n)
{
if(cur == n)
{
for(int i = 0; i < n; i++)
{
cout << A[i] << ' ';
}
cout << endl;
}
else
{
for(int i = 1; i <= n; i ++)
{
bool flag = true;
for(int j = 0; j < cur; j ++)
{
if(i == A[j])
{
flag = false;
}
}
if(flag)
{
A[cur] = i;
f(A,cur + 1,n);
}
}
}
}
int main()
{
int n;
cin >> n;
int A[10000];
f(A,0,n);
return 0;
}
2、
#include<iostream>
using std::cin;
using std::cout;
using std::endl;
void f(int A[], int cur, int n)
{
if(cur == n)
{
for(int i = 0; i < n; i++)
{
cout << A[i] << ' ';
}
cout << endl;
}
else
{
for(int i = 1; i <= n; i ++)
{
A[cur] = i;
f(A,cur + 1,n);
}
}
}
int main()
{
int n;
cin >> n;
int A[10000];
f(A,0,n);
return 0;
}
3、
#include<iostream>
using std::cin;
using std::cout;
using std::endl;
void f(int P[],int A[], int cur, int n)
{
if(cur == n)
{
for(int i = 0; i < n; i++)
{
cout << A[i] << ' ';
}
cout << endl;
}
else
{
for(int i = 0; i < n; i ++)if(i == 0 || P[i] != P[i - 1])
{
int c1 = 0, c2 = 0;
for(int j = 0; j < cur; j ++)
{
if(A[j] == P[i])
{
c1 ++;
}
}
for(int j = 0; j < n; j ++)
{
if(P[j] == P[i])
{
c2 ++;
}
}
if(c1 < c2)
{
A[cur] = P[i];
f(P, A, cur + 1, n);//注意cur只能这么加值,保证相同父结点的cur相同,孩子结点比父亲结点多1.
}
}
}
}
int main()
{
int n;
cin >> n;
int P[10000];
for(int i = 0; i < n; i ++)
{
cin >> P[i];
}
int A[10000];
f(P,A,0,n);
return 0;
}
4、
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int n,p[10];
cin >> n;
for(int i = 0; i < n; i ++)
{
cin >> p[i];
}
sort(p, p + n);
do
{
for(int i = 0; i < n; i ++)
{
cout << p[i] << ' ';
}
cout << endl;
}while(next_permutation(p, p + n));
return 0;
}