package decreaseAndConquer; /* * 实现用来生成排列的Johnson-Trotter算法 * 输入:一个正整数n * 输出:{1,...,n}的所有排列的列表 */ import java.util.*; public class JohnsonTrotter { static int elements[]; static int direaction[]; static int k;//用于保存最大的移动元素在数组中的位置 static int count = 0;//用于保存生成的排列总数 static void permutation(int n){ elements = new int[n+1]; direaction = new int[n+1];//表示元素的箭头的指向,1表示指向左,0表示指向右 for(int i=1;i<=elements.length-1;i++){ elements[i] = i; direaction[i] = 1;//初始化所有箭头指向左 } output(elements); while(exitMobileElement(elements)){//如果存在移动元素 if(direaction[k]==1){//如果箭头向左 if(k>1&&elements[k]>elements[k-1]){ //交换两个元素的位置 int temp = elements[k]; elements[k] = elements[k-1]; elements[k-1] = temp; //同时,还要交换两个元素的箭头指向位置 temp = direaction[k]; direaction[k] = direaction[k-1]; direaction[k-1] = temp; output(elements); k--; //调转所有大于arr[k]的元素的方向 for(int i=1;i<=elements.length-1;i++){ if(elements[i]>elements[k]){ direaction[i] = 1-direaction[i]; } } } } else{//箭头向右 if(k<elements.length-1&&elements[k]>elements[k+1]){ //交换两个元素的位置 int temp = elements[k]; elements[k] = elements[k+1]; elements[k+1] = temp; //同时,还要交换两个元素的箭头指向位置 temp = direaction[k]; direaction[k] = direaction[k+1]; direaction[k+1] = temp; output(elements); k++; //调转所有大于arr[k]的元素的方向 for(int i=1;i<=elements.length-1;i++){ if(elements[i]>elements[k]){ direaction[i] = 1-direaction[i]; } } } } }//while }//Permutation static boolean exitMobileElement(int arr[]){//判断是否存在移动元素,并求出最大的移动元素,将其位置保存在k int tag = 0; k = 0; arr[k] = 0; for(int i=1;i<=arr.length-1;i++){ if(i==1){//判断第一个元素 if(arr[i]>arr[i+1]&&direaction[i]==0){ tag = 1; if(arr[i]>arr[k]){ k = i;//arr[i]为当前最大移动元素 } } } else if(i==arr.length-1){//判断最后一个元素 if(arr[arr.length-1]>arr[arr.length-2]&&direaction[arr.length-1]==1){ tag = 1; if(arr[i]>arr[k]){ k = i;//arr[i]为当前最大移动元素 } } } else{//判断中间的元素 if((arr[i]>arr[i-1]&&direaction[i]==1)||(arr[i]>arr[i+1]&&direaction[i]==0)){ tag = 1; if(arr[i]>arr[k]){ k = i;//arr[i]为当前最大移动元素 } } } } if(tag==1){ return true; } else{ return false; } } //输出排列 static void output(int arr[]){ count++; for(int i=1;i<=arr.length-1;i++){ System.out.print(arr[i]+" "); } System.out.println(); } public static void main(String[] args) { Scanner in = new Scanner(System.in); System.out.println("请输入一个正整数n:"); int n = in.nextInt(); in.close(); System.out.println("排列如下:"); permutation(n); System.out.println("一共有"+count+"个排列。"); } }