全排列邻位对换法c语言算法,全排列——邻位对换法.docx

全排列—— 位 法

(算法)全排列—— 位 法

一个能 快速生成全排列的算法叫做 位 法,它之所以 快,是因 位 法中下一个排列 是上一个排列某相

两位 得到的, 只需一步, 就可以得到一个新的全排列,而且 不重复,但是由于每将 n 从一端移 到另一端后,就需要遍 排列 2 次,来 找最大的可移数 m ,所以速度得到了限制。它的原理是:

的全排列可由 [n-1] 的全排列生成:

定 [n-1] 的一个排列 п , 将n 由最右端依次插入排列得到 n 个[n] 的排列:

п ,即

P1 P2

?

P(n -1) n

P1 P2

?

n P(n -1)

n P1 P2

?

P(n-1)

上述 程,一般地,

i,将前一步所得的每一排列重复

i

次,然后将i 由第一排的最后往前移,至最前列,正好走了

i 次 ,下一个接着将i 放在下一排列的最前面,然后依次往后

移,一直下去即得i 元排列。

考 {1,2 ? n} 的一个排列,其上每一个整数都 了一个方向,

如果它的箭 所指的方向的 点小于它本身,我 称整数k

是可移的。

然 1 永 不可移, n 除了以下两种情形外,它都是可移的:

n 是第一个数,且其方向指向左

n 是最后一个数,且其方向指向右 于是,我 可按如下算法 生所有排列:

1,开始 :存在排列123? n,除1 外,所有元素均可移,

即方向都指向左 。

2,当最大元素 n 可移 ,将其从一端依次移 到另一端,即可得到 n-1 个全排列;当 n 移 到某一端后, 不能再移 ,此 找最大的可移数 m ,将 m 与其箭 所指的 数 ( 个数当然不会是 N,否 怎么可移 )

互 位置, 就又得到一个新的全排列;将所得新排列中

所有比 m 大的数 p 的方向 整, 即改 相反方向, 使得

又成了可移数。

3,重复第2 步直到所有的元素都不能移 止。

以 4 个元素的排列 例,首先生成全排列

1234;

找到最大的可移数4,将 4 与其箭 所指的 数互 位置,

可以生成 3 个新排列:

1243

1423

4123

因为没有比4 更大的数 p,所以无需调整p 的方向。最大数

4 到了最左边后, 由于其方向指向左侧, 所以 4 不能再移动。

接下来寻找最大的可移数

3,将

3 与其箭头所指的邻数

2 互

换位置,可以得到新排列:

4132

然后将所得排列中比

3 大的数

4 的方向调整, 使得

4 可以移

动,重新成为最大的可移数,将

4 与其箭头所指的邻数互换

位置,可以生成

3 个新排列:

1432

1342

1324

此时最大数

4

到了最右边,又因为其方向指向右侧,所以

4

不能再移动;于是我们寻找最大的可移数

3,将 3 与其箭头

所指的邻数

1

互换位置,可以得到新排列:

3124;

然后将所得排列中比3 大的数 4 的方向调整, 使得 4 可以移

动,重新成为最大的可移数,将4 与其箭头所指的邻数互换

位置,可以生成3 个新排列:

3142

3412

4312

如此循环,直到所有的数都不能移动,即可求出全部排列。

最后得到的一个全排列为:2 1 3 4 ,此时 2 指向左侧, 1,3,

均指向右侧。

根据上述算法分析,使用一个辅助数组来存储各个元素的指

向,我们可以得到代码如下:

/*

函数名称: Permutation

函数功能:排列邻位对换法:输出n 个数的所有全排列

输入变量: int n : 1, 2, 3, ... ,n 共 n 个自然数

输出变量:无

*/

void Permutation(int n)

{

int *a = new int[n]; //用来存储n 个自然数

bool *p = new bool[n]; //用来存储n 个元素的指向:向左

为 false ,向右为 true

for (int i=0; i

排列的数量

{

a[i] = i + 1;

p[i] = false; // 开始均指向左侧

}

do

{

Print(a, n); // 输出第一个全排列

if (n == a[n-1])// 若 n 在最右侧,将其逐次与左侧的元素交换,得到 n - 1 个新的排列

{

for (int i=n-1; i>0; i--)

{

int temp = a[i]; a[i] = a[i-1]; a[i-1] = temp;

bool flag = p[i]; p[i] = p[i-1]; p[i-1] = flag;

Print(a, n);

}

}

else

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值