全排列算法
标签(空格分隔): 算法 全排列
全排列算法的两种算法分析及代码详解
The first one Algoritnm
描述:将一组一维数据分成左右两部分,,左边为m个数据,右边为n-m个数据,再假设左边的数据是已经进行完全排列的状态,那么用一个for循环将右边的n-m个数依次与右边第一个作交换,并且每一个交换都递归调用perm1函数(下文有说明)且每一次递归后将数据交换回来,伪码表示如下:
输入:正整数n。
输出:数1,2,3,4,。。。n的所有可能排列
- for j<-1 to n
- p[j]<-j
- end for
- perm1(1)(此处表示从第一个数开始进行全排列,如果是代码数组则是0)
过程 perm(m):
- if m=n then output P[1…n]
- else
- for j<- m to n
- 互换P[j]和P[m]
- perm1(m+1)
- 互换P[j]和p[m]
- comment:这是P[m…n]=m,m+1,…,n
- end for
- end if
代码
#include <iostream>
using namespace std;
int p[100];//设定全局变量因为需要在函数里面调用,在主函数定义的话使用不了
int n;
void swap(int &x,int &y){//交换数据
int temp;
temp = x;
x = y;
y = temp;
}
void perm1(int m) {//递归实现全排列,m是开始排列的下标,一般为0开始表示全排列
if (m == n) {
for (int i = 0; i < n; i++)
cout << p[i] << ‘\t’;
cout << endl;
}
else
for (int j = m; j < n; j++) {
swap(p[j], p[m]);
perm1(m + 1);
swap(p[j], p[m]);
}
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++)//给数据赋值
p[i - 1] = i;
perm1(0);
system(“pause”);
}
(markdown画不了图,本地照片要99块高级会员,,,,所以原谅我没有画图吧)
算法复杂度为O(n*n!)
(至于怎么算的我之后再补充)
the second algorithm
伪码
输入:正整数n.
输出:数1,2,…,n的所有可能排列
- for j <-1 to n
- p[j]<-0
- end for
- perm2(n)
过程:
perm2(m)
- if m=0 then output P[1…n]
- else
- for j<- 1 to n
- if P[j]=0 then
- P[j]<-m
- perm2(m-1)
- P[j]<-0
- endif
- end for
- end if
###详解:
首先将一个一维数据全赋初值为0,然后从最大得数m开始排列,从1到m的位置选一个不为0的P[j]=m,在p[j]=m的基础上再把m-1在剩下不为0的数中放,如此递归直到m=0此时递归结束,以上我们实现了,m在某一个位置上的全排列,想实现真正的全排列,只需要用一个循环将m赋给p[1…n]
##代码
#include <iostream>
using namespace std;
//全局变量
int n;
int p[100];
//递归求全排列,m是最大的要排列的数
void perm2(int m) {
if (m == 0) {
for (int i = 0; i < n; i++)
cout << p[i] << ‘\t’;
cout << endl;
}
else
for (int j = 0; j <n; j++) {
if (p[j] == 0) {
p[j]=m;
//这一步开始往后三步是重点,将m赋给p[j],然后在递归调用perm2(m-1),先循环排好m的位置,再递归排m-1。。。直到0递归结束。
perm2(m - 1);
p[j] = 0;
}
}
}
int main() {
cin >> n;
for (int i = 0; i < n; i++)
p[i] = 0;
perm2(n);
system(“pause”);
}