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)算法求全排列的更多相关文章

  1. Johnson-Trotter(JT)算法生成排列

        对于生成{1,……,n}的所有n!个排列的问题,我们可以利用减治法,该问题的规模减一就是要生成所有(n-1)!个排列.假设这个小问题已经解决了,我们可以把n插入到n-1个元素的每一种排列中的n ...

  2. LeetCode46 回溯算法求全排列,这次是真全排列

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode的26篇文章,我们来实战一下全排列问题. 在之前的文章当中,我们讲过八皇后.回溯法,也提到了全排列,但是毕竟没有真正写 ...

  3. 求全排列Permutation

    是在教材(<计算机算法设计与分析(第4版)>王晓东 编著)上看见的关于求全排列的算法: 我们可以看一下书上怎么写的: #include<bits/stdc++.h> using ...

  4. PermutationsUnique,求全排列,去重

    问题描述:给定一个数组,数组里面有重复元素,求全排列. 算法分析:和上一道题一样,只不过要去重. import java.util.ArrayList; import java.util.HashSe ...

  5. 蓝桥杯--算法提高 排列数 (简单dfs)

    算法提高 排列数   时间限制:1.0s   内存限制:256.0MB      问题描述 0.1.2三个数字的全排列有六种,按照字母序排列如下: 012.021.102.120.201.210 输入 ...

  6. Java实现 蓝桥杯VIP 算法训练 排列问题

    算法训练 排列问题 时间限制:1.0s 内存限制:512.0MB 问题描述 求一个0-N-1的排列(即每个数只能出现一次),给出限制条件(一张N*N的表,第i行第j列的1或0,表示为j-1这个数不能出 ...

  7. cb47a_c++_STL_算法_排列组合next_prev_permutation

    cb47a_c++_STL_算法_排列组合next_prev_permutation 使用前必须先排序.必须是 1,2,3或者3,2,1.否者结果不准确.如果, 1,2,4,6.这样数据不会准确nex ...

  8. LeetCode:Permutations, Permutations II(求全排列)

    Permutations Given a collection of numbers, return all possible permutations. For example, [1,2,3] h ...

  9. 算法笔记_099:蓝桥杯练习 算法提高 排列数(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 0.1.2三个数字的全排列有六种,按照字母序排列如下: 012.021.102.120.201.210 输入一个数n 求0~9十个数的全排 ...

随机推荐

  1. 神奇的 SQL 之 ICP → 索引条件下推

    开心一刻 楼主:来,我们先排练一遍 小伙伴们:好 嘿.哈.嚯 楼主:非常好,就是这个节奏,我们开始吧 楼主:啊.啊.啊,疼 ! 你们是不是故意的 ? 回表与覆盖索引 正式讲 ICP 之前了,我们先将相 ...

  2. 峰哥说技术:03-Spring Boot常用注解解读

    Spring Boot深度课程系列 峰哥说技术—2020庚子年重磅推出.战胜病毒.我们在行动 03 Spring Boot常用注解解读 在Spring Boot中使用了大量的注解,我们下面对一些常用的 ...

  3. Python学习之布尔和数字

    布尔有True和Flase两种值 数字0.None,以及元素为空的容器类对象都可视为False,反之为Ture.

  4. Overt.GrpcTemplate.Service 模板使用教程

    阅读这篇文章需要先阅读我的另外一篇文章,目前还未发布出来,待发布中... 1. Overt.GrpcTemplate.Service .Net Core 3.1 版本 模板名称改成 Overt.Grp ...

  5. 学习 CSS 之用 CSS 3D 实现炫酷效果

    一.前言 把大象关进冰箱需要几步?三步,把冰箱门打开,把大象关进去,把冰箱门关上. 用 CSS 实现 3D 效果需几步?三步,设置透视效果 perspective,改变元素载体为 preserve-3 ...

  6. node 微信支付

    基于node 实现微信支付功能 需要了解的网站:微信支付 流程图: 1. 1.我的路由: const Koa = require('koa') const app = new Koa() const ...

  7. 测试必知必会系列- Linux常用命令 - history

    21篇测试必备的Linux常用命令,每天敲一篇,每次敲三遍,每月一循环,全都可记住!! https://www.cnblogs.com/poloyy/category/1672457.html 查看历 ...

  8. Natas23 Writeup(php弱类型)

    Natas23: 一个登录页面,查看源码,发现关键代码: if(array_key_exists("passwd",$_REQUEST)){ if(strstr($_REQUEST ...

  9. Fiddler1 简单使用

    1.Fiddler下载地址:https://www.telerik.com/download/fiddler 2.Fiddler设置: Fiddler是强大的抓包工具,它的原理是以web代理服务器的形 ...

  10. Linux常用命令 - wget命令详解(重点)

    21篇测试必备的Linux常用命令,每天敲一篇,每次敲三遍,每月一循环,全都可记住!! https://www.cnblogs.com/poloyy/category/1672457.html 下载i ...