Johnson-Trotter(JT)算法求全排列
Johnson-Trotter算法描述
算法 JohnsonTrotter(n)
//实现用来生成排序的 Johnson-Trotter 算法
//输入:正整数n(代表序列1,2,···,n)
//输出:{1,2,···,n}的全排列
将第一个全排列初始化为
while 存在一个移动元素 do
求最大的移动元素 k
把 k 和它箭头指向的相邻元素互换
调转所有大于 k 的元素的方向
将新排列添加到排列中
以 n=3 为例

下面我将贴出Johnson-Trotter算法的JAVA代码
package JT;
import java.util.Scanner;
public class Johnson_Trotter {
//求最大的移动元素
public static int maxk(int n, int[] array, boolean[] f) {
//k存储最大移动元素的下标
int k = -1, max = 0;
for(int i = 0; i < n; i++) {
//当前元素的方向是左边,则与左边的元素比较看是否可以移动
//若可移动则与当前可移动最大值比较
if(f[i] == false) {
if(i > 0 && array[i] > array[i - 1] && array[i] > max) {
k = i;
max = array[i];
}
}
//右边
else {
if(i < n - 1 && array[i] >array[i + 1] && array[i] > max) {
k = i;
max = array[i];
}
}
}
return k;
}
//元素和方向的交换
public static int[] swap2(int[] array, boolean[] f, int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
boolean temp1 = f[i];
f[i] = f[j];
f[j] = temp1;
return array;
}
//调转方向
public static boolean[] Reverseid(int[] array, int k, boolean[] f) {
for(int i = 0; i < array.length; i++) {
if(array[i] > array[k]) {
f[i] = f[i] ? false : true;
}
}
return f;
}
public static void Jt(int n) {
//方向数组,false为左,true为右
boolean[] flag = new boolean[n];
//数字数组
int[] idata = new int[n];
//k为当前可移动元素的最大值
int k = 0;
//初始化两个数组
for(int i = 0; i < n; i++) {
idata[i] = i + 1;
flag[i] = false;
}
//输出第一个初始化的排列,此排列不会自动生成
for(int i = 0; i < n; i++) {
System.out.print(idata[i]);
System.out.print(flag[i]);
}
System.out.println();
//初始化k,获取第一个可移动的最大元素
k = maxk(n, idata, flag);
//循环直到没有可移动的元素
while(k != -1) {
//可向右移动
if(flag[k]) {
//移动时,将元素和方向都交换
idata = swap2(idata, flag, k, k + 1);
//此时k所在的元素已经向右交换,k也需要对应加1
k++;
}
//可向左移动
else {
idata = swap2(idata, flag, k, k - 1);
k--;
}
flag = Reverseid(idata, k, flag);//调转所有大于k的元素的方向
//输出当前的一个排列
for(int i = 0; i < n; i++) {
System.out.print(idata[i]);
System.out.print(flag[i]);
}
System.out.println();
k = maxk(n, idata, flag);//获取下一个k
}
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();//输入n
Jt(n);//调用算法
scan.close();
}
}
代码运行结果如下:(带有元素方向)
Please put in n :4
1false2false3false4false
1false2false4false3false
1false4false2false3false
4false1false2false3false
4true1false3false2false
1false4true3false2false
1false3false4true2false
1false3false2false4true
3false1false2false4false
3false1false4false2false
3false4false1false2false
4false3false1false2false
4true3true2false1false
3true4true2false1false
3true2false4true1false
3true2false1false4true
2false3true1false4false
2false3true4false1false
2false4false3true1false
4false2false3true1false
4true2false1false3true
2false4true1false3true
2false1false4true3true
2false1false3true4true
Process finished with exit code 0
此文章为原创,转载需说明出处。
Johnson-Trotter(JT)算法求全排列的更多相关文章
- Johnson-Trotter(JT)算法生成排列
对于生成{1,……,n}的所有n!个排列的问题,我们可以利用减治法,该问题的规模减一就是要生成所有(n-1)!个排列.假设这个小问题已经解决了,我们可以把n插入到n-1个元素的每一种排列中的n ...
- LeetCode46 回溯算法求全排列,这次是真全排列
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode的26篇文章,我们来实战一下全排列问题. 在之前的文章当中,我们讲过八皇后.回溯法,也提到了全排列,但是毕竟没有真正写 ...
- 求全排列Permutation
是在教材(<计算机算法设计与分析(第4版)>王晓东 编著)上看见的关于求全排列的算法: 我们可以看一下书上怎么写的: #include<bits/stdc++.h> using ...
- PermutationsUnique,求全排列,去重
问题描述:给定一个数组,数组里面有重复元素,求全排列. 算法分析:和上一道题一样,只不过要去重. import java.util.ArrayList; import java.util.HashSe ...
- 蓝桥杯--算法提高 排列数 (简单dfs)
算法提高 排列数 时间限制:1.0s 内存限制:256.0MB 问题描述 0.1.2三个数字的全排列有六种,按照字母序排列如下: 012.021.102.120.201.210 输入 ...
- Java实现 蓝桥杯VIP 算法训练 排列问题
算法训练 排列问题 时间限制:1.0s 内存限制:512.0MB 问题描述 求一个0-N-1的排列(即每个数只能出现一次),给出限制条件(一张N*N的表,第i行第j列的1或0,表示为j-1这个数不能出 ...
- cb47a_c++_STL_算法_排列组合next_prev_permutation
cb47a_c++_STL_算法_排列组合next_prev_permutation 使用前必须先排序.必须是 1,2,3或者3,2,1.否者结果不准确.如果, 1,2,4,6.这样数据不会准确nex ...
- LeetCode:Permutations, Permutations II(求全排列)
Permutations Given a collection of numbers, return all possible permutations. For example, [1,2,3] h ...
- 算法笔记_099:蓝桥杯练习 算法提高 排列数(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 0.1.2三个数字的全排列有六种,按照字母序排列如下: 012.021.102.120.201.210 输入一个数n 求0~9十个数的全排 ...
随机推荐
- .Net 特性分析与妙用
一.特性是什么 1.想象很多小伙伴们都看过在一个类上方.或者在控制器见过类似的东东,加上之后就可以标识这个类或者方法就具备了某些特点 ,那我们就进入它的内心一探究竟吧. 2.我们进入某个特性之后,可以 ...
- Cake URAL - 1755
1755. Cake Time limit: 0.5 secondMemory limit: 64 MB Karlsson and Little Boy have found a cake in th ...
- Spring Cloud Gateway 实现Token校验
在我看来,在某些场景下,网关就像是一个公共方法,把项目中的都要用到的一些功能提出来,抽象成一个服务.比如,我们可以在业务网关上做日志收集.Token校验等等,当然这么理解很狭隘,因为网关的能力远不止如 ...
- Java——JDBC
今天给大家更新一篇我自己学习Java——JDBC的经验 Java中JDBC是(Java DataBase Connectivity)的简称,由java语言编写的类和接口组成,可为多种关系型数据库提供了 ...
- Windows环境下docker的安装与配置
Docker是一种容器技术,可以在操作系统中隔离出若干个独立的程序运行环境,这些环境既可以共享宿主机的资源,另一方面他们之间相互独立,互不影响,也不会对宿主机的环境产生影响.与虚拟化技术不同的是,Do ...
- java并发编程基础概念
本次内容主要讲进程和线程.CPU核心数和线程数.CPU时间片轮转机制.上下文切换,并行和并发的基本概念以及并发编程的好处和注意事项,为java并发编程打下扎实基础. 1.什么是进程和线程 1.1 进程 ...
- JavaScript的类数组
类数组对象啊,被人问到它跟真正的数组对象有什么差别啊?说不上来就老埋汰了,只知道函数的arguments对象是个类数组对象,也有length属性,其他呢?干货奉上: 首先先说说数组吧: 1,当有新的元 ...
- 最全Redis基础知识
NoSQL概述 什么是NoSQL NoSQL不仅仅是SQL,它是Not Only SQL 的缩写,也是众多非关系型数据库的统称NoSQL和关系型数据库一样,也是用来存储数据的仓库. 为什么需要NoSQ ...
- Iterm2 快捷操作
窗口操作 新建窗口:Command + N 关闭所有窗口:Shift + Command + W 窗口之间切换 前一个窗口: Command + [ 后一个窗口:Command + ] 进入窗口1,2 ...
- vue中计算属性中的set和get
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <body& ...