通过上篇文章可以看到,如果想要生成{1,2.....,n}的全排列,那么在生成的过程中我们需要将{1} {1,2} {1,2,3} ...... {1,2,3.....n}的排列进行保存。那么如何才能做到,排列覆盖当前排列而不必保留所有排列呢?
Even 给出一种描述如下:
生成{1,2,.....n}的排列算法
从1,2,3,n开始(<--- 每一个数字都需要加上方向)
可移动:当数字指向方向上的相邻数字比该数字小时那么表示该数字可以移动。当然当处于集合开始,或者结尾,并且方向是向左或者向右时是不可移动的。
(1)求出最大的可移动整数m
(2)交换m和它的箭头所指的方向的与它相邻的整数
(3)交换所有满足p>m的整数p上的箭头的方向。(m经过交换后变成不可移动,然后找到次大来代替m,此时将m重新赋值,那么必然有原始的值大于当前m此整数便是p)
import java.util.Arrays;
public class DirectionSortArray {
Number[] numbers;
public class Number{
int index;
int value;
Direction direction;
}
enum Direction{
left,right
}
public String arrayToString(Number[] numbers){
int[] temp = new int[numbers.length];
int i = 0;
for(Number number : numbers){
temp[i++] = number.value;
}
return Arrays.toString(temp);
}
public Number getBiggest(Number[] numbers){
Number temp = null;
for(int i = 0;i < numbers.length;i++){
if(isMoveable(numbers[i],i,numbers) && (temp == null || temp.value < numbers[i].value)){
temp = numbers[i];
}
}
return temp;
}
public boolean isMoveable(Number number,int index,Number[] numbers){
if(index == numbers.length - 1 && number.direction == Direction.right){
return false;
}else if(index == 0 && number.direction == Direction.left){
return false;
}else{
Number nextNumber = null;
if(number.direction == Direction.left){
nextNumber = numbers[index - 1];
}else{
nextNumber = numbers[index + 1];
}
if(nextNumber.value > number.value){
return false;
}
}
return true;
}
//进行交换
public void swap(Number bigNumber,Number[] numbers){
//直接进行交换
int changedIndex = 0;
if(bigNumber.direction == Direction.right){
changedIndex = bigNumber.index + 1;
}else if(bigNumber.direction == Direction.left){
changedIndex = bigNumber.index - 1;
}
numbers[bigNumber.index] = numbers[changedIndex];
numbers[bigNumber.index].index = bigNumber.index;
numbers[changedIndex] = bigNumber;
numbers[changedIndex].index = changedIndex;
bigNumber.index = changedIndex;
//判断当前Number是否可移动
if(!isMoveable(bigNumber, changedIndex,numbers)){
//不可移动时找到次大值,交换方向后,将比它大的所有数字方向进行变换
bigNumber = getBiggest(numbers);
if(bigNumber == null){
return;
}
System.out.println(arrayToString(numbers));
changeDirection(bigNumber,numbers);
//进行一次交换
swap(bigNumber,numbers);
}
}
public void changeDirection(Number number,Number[] numbers){
for(Number temp : numbers){
if(temp.value > number.value){
if(temp.direction == Direction.left){
temp.direction = Direction.right;
}else{
temp.direction = Direction.left;
}
}
}
}
//初始化数据
public void init(){
numbers = new Number[4];
for(int i = 0;i < numbers.length;i++){
numbers[i] = new Number();
numbers[i].direction = Direction.left;
numbers[i].value = i + 1;
numbers[i].index = i;
}
}
//进行排序
public void sort(){
Number bigNumber = getBiggest(numbers);
while(bigNumber != null){
System.out.println(arrayToString(numbers));
//找出最大的number
swap(bigNumber, numbers);
bigNumber = getBiggest(numbers);
}
System.out.println(arrayToString(numbers));
}
public static void main(String[] args) {
DirectionSortArray array = new DirectionSortArray();
array.init();
array.sort();
}
}