java 全排列非递归算法_全排列算法的非递归实现与递归实现的方法(C++)

(一)非递归全排列算法基本思想是:    1.找到所有排列中最小的一个排列P.

2.找到刚刚好比P大比其它都小的排列Q,

3.循环执行第二步,直到找到一个最大的排列,算法结束.

下面用数学的方法描述:

给定已知序列 P =  A1A2A3An ( Ai!=Aj , (1<=i<=n  , 1<=j<=n, i != j  ) )

找到P的一个最小排列Pmin = P1P2P3Pn  有  Pi > P(i-1) (1 < i <= n)

从Pmin开始,总是目前得到的最大的排列为输入,得到下一个排列.

方法为:1.从低位到高位(从后向前),找出“不符合趋势”的数字。即找到一个Pi,使Pi < P(i+1)。

若找不到这样的pi,说明我们已经找到最后一个全排列,可以返回了。

2.在 P(i+1)P(i+2)Pn 中,找到一个Pj,便得 Pj"刚刚好大于"Pi.

("刚刚好大于"的意思是:在 P(i+1)P(i+2)Pn 中所有大于Pi的元素构成的集合中最小的元素.)

3.交换 Pi , Pj 的位置.注意:此处不改变i和j的值,改变的是Pi和Pj.

4.交换后, P1P2P3Pn  并不是准确的后一个排列。因为根据第1步的查找,我们有P(i+1) > P(i+2) > . > Pn

即使进行了Pi和Pj的交换,这仍然是这一部分最大的一个排列。将此排列逆序倒置(变成最小的排列)即为所求的下一个排列.

5.重复步骤1-4,直到步骤1中找不到“不符合趋势”的数字.

//交换数组a中下标为i和j的两个元素的值

void swap(int* a,int i,int j)

{

a[i]^=a[j];

a[j]^=a[i];

a[i]^=a[j];

}

//将数组a中的下标i到下标j之间的所有元素逆序倒置

void reverse(int a[],int i,int j)

{

for(;i

{

swap(a,i,j);

}

}

void print(int a[],int length)

{

for(int i=0;i

cout<

cout<

}

//求取全排列,打印结果

void combination(int a[],int length)

{

if(length<2) return;

bool end=false;

while(true)

{

print(a,length);

int i,j;

//找到不符合趋势的元素的下标i

for(i=length-2;i>=0;--i)

{

if(a[i]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值