排列的生成算法

字典序法

对于按字典的顺序给出的排列(p=p(1)p(2)p(3)p(4)…p(n)),由一个排列生成下一个排列的算法如下:

(1)求满足关系式p(j-1)<p(j)的j的最大值设为i,即 i=max{j|p(j-1)<p(j)}

(2)求满足关系式p(i-1)<p(k)的k的最大值设为j,即 j=max{k|p(i-1)<p(k)}

(3)p(i-1)与p(j)互换位置,得到p‘=p(1)p(2)…p(n)

(4)在p‘=p(1)p(2)…p(i-1)p(i)p(i+1)…p(n)中,把p(i)p(i+1)…p(n)部分逆序,所得p=p(1)p(2)…p(i-1)p(n)p(n-1)…p(i)序列就是所求。其中j的意义是排列的下标,对于一个有n个数的排列,j的范围是从0到n。p(j)就是这个排列的第j个数。

附源码:

var

p:array[0..1000]of longint;

i,n,j,k,t:longint;

begin

readln(n);

for i:=1 to n do p[i]:=i;

repeat

for i:=1 to n do write(p[i],‘ ‘); writeln;

for j:=1 to n do if p[j-1]<p[j] then i:=j;

for k:=1 to n do if p[i-1]<p[k] then j:=k;

t:=p[i-1];  p[i-1]:=p[j];  p[j]:=t;

for k:=i to (i+n)shr 1 do

begin

t:=p[k]; p[k]:=p[n-k+i]; p[n-k+i]:=t;

end;

until i=1;

end.

时间: 2025-01-17 02:39:19

排列的生成算法的相关文章

排列组合生成算法

r排列生成: gen 递归层数d表示正在生成第d个元素. vis记录是否出现过. #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n, r; int A[50], vis[50];//记录第i个元素是否生成过 int cnt; int rer; void output(int r) { for(int i = 0; i < r; i++) printf(

[LeetCode] Permutations 排列生成算法之字典序法

字典序排序生成算法 字典序法就是按照字典排序的思想逐一产生所有排列. 例如,由1,2,3,4组成的所有排列,从小到大的依次为: 1234, 1243, 1324, 1342, 1423, 1432, 2134, 2143, 2314, 2341, 2413, 2431, 3124, 3142, 3214, 3241, 3412, 3421, 4123, 4132, 4213, 4231, 4312, 4321. 分析这种过程,看后一个排列与前一个排列之间有什么关系? 再如,设有排列(p)=276

排列生成算法--C++

1 #include<iostream> 2 using namespace std; 3 //初始化,注意两边的初始化,简化算法 4 void Init(int n , int *arr , bool * flags) 5 { 6 arr[0] = 0xfffffff; 7 for(int i = 1;i <= n;i++) 8 { 9 arr[i] = i; 10 flags[i] = false; 11 } 12 arr[n+1] = 0xfffffff; 13 } 14 //检查

[原创][网页游戏]数独生成算法及实例

[ 程序修正 2015/02/23 补充及订正方法:iphone上的Safari会自动对看起来像是电话号码的数字串(包括已经加入连字符或括号格式化过的)添加电话链接,点击之后会询问用户是否想要拨打该号码. 关闭方法: <meta name="format-detection" content="telephone=no" /> 单独开放方法: <a href="tel:13800138000">13800138000<

简单探讨全排列的生成算法

在研究组合数学的时候,常常能够碰见要求生成全排列的情况.下面来简单探讨全排列的递归生成算法. 现有一个序列(1,2,3),将其命名为序列S<a1,a2,a3>, 假定A(a1,a2,a3) 为这个序列的全排列,那么我们可以得到如下若干序列: <a1,A(a2,a3)>  ① <a2,A(a1,a3)>  ② <a3,A(a1,a2)>  ③ 我们再来看①,她还可以展开成如下两个序列: <a1,a2,A(a3)>  ⑤ <a1,a3,A(a2

基于字典序的组合生成算法

基于字典序的组合生成算法 2010-12-02 01:22:52|  分类: 离散数学 |  标签:离散数学  排列组合   |举报 |字号大中小 订阅 一. 问题描述 给定非空集合A,按字典序的方法生成集合A的所有组合.关于字典序的概念,这里不做严格定义,只是做一简单解释. 字典序是字符串比较的一种方法.例如两个字符串 abcd,abef,这两个字符串谁大? 显然,abef>abcd:如何得出这个结论的呢? 从左至右依次比较每一个字符,首先比较两个串的第一个字符,都是a,相等:其次比较两个串的

全排列的生成算法

[复制转载] //全排列的生成算法 // 全排列的生成算法就是对于给定的字符集,用有效的方法将所有可能的全排列无重复无遗漏地枚举出来.任何n个字符集的排列都可以与1-n的n个数字的排列一一对应, // 因此在此就以n个数字的排列为例说明排列的生成法. // n个字符的全体排列之间存在一个确定的线性顺序关系.所有的排列中除最后一个排列外,都有一个后继:除第一个排列外,都有一个前驱.每个排列的后继都可以从 // 它的前驱经过最少的变化而得到,全排列的生成算法就是从第一个排列开始逐个生成所有的排列的方

递归解决全排列生成算法

排列:从n个元素中任取m个元素,并按照一定的顺序进行排列,称为排列: 全排列:当n==m时,称为全排列: 比如:集合{ 1,2,3}的全排列为: { 1 2 3} { 1 3 2 } { 2 1 3 } { 2 3 1 } { 3 2 1 } { 3 1 2 } 方法一: 我们可以将这个排列问题画成图形表示,即排列枚举树,比如下图为{1,2,3}的排列枚举树,此树和我们这里介绍的算法完全一致: 算法思路: (1)n个元素的全排列=(n-1个元素的全排列)+(另一个元素作为前缀): (2)出口:如

枚举排列 之 “生成1~n的排列”

一.原题 输入n之后,生成1~n的排列. (题目来源:<算法竞赛入门经典>[刘汝佳]) 二.题目源代码 #include <stdio.h> #define MAXN 1000 int a[MAXN][MAXN]; void print_permutation(int n,int*a,int cur) { int i,j; if(cur==n) //递归边界 { for(i=0;i<n;i++) printf("%d",a[i]); printf(&quo