全排列算法 两种

全排列算法

标签(空格分隔): 算法 全排列


全排列算法的两种算法分析及代码详解

The first one Algoritnm

描述:将一组一维数据分成左右两部分,,左边为m个数据,右边为n-m个数据,再假设左边的数据是已经进行完全排列的状态,那么用一个for循环将右边的n-m个数依次与右边第一个作交换,并且每一个交换都递归调用perm1函数(下文有说明)且每一次递归后将数据交换回来,伪码表示如下:

输入:正整数n。
输出:数1,2,3,4,。。。n的所有可能排列

  1. for j<-1 to n
  2. p[j]<-j
  3. end for
  4. perm1(1)(此处表示从第一个数开始进行全排列,如果是代码数组则是0)

过程 perm(m):

  1. if m=n then output P[1…n]
  2. else
  3. for j<- m to n
  4. 互换P[j]和P[m]
  5. perm1(m+1)
  6. 互换P[j]和p[m]
  7. comment:这是P[m…n]=m,m+1,…,n
  8. end for
  9. 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的所有可能排列

  1. for j <-1 to n
  2. p[j]<-0
  3. end for
  4. perm2(n)

过程:
perm2(m)

  1. if m=0 then output P[1…n]
  2. else
  3. for j<- 1 to n
  4. if P[j]=0 then
  5. P[j]<-m
  6. perm2(m-1)
  7. P[j]<-0
  8. endif
  9. end for
  10. 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”);
}

算法复杂度:O(n*n!)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值