JAVA-给定个数对象的全排列原理

一直都不太理解递归,这次写全排列的时候找到一张图最为简单的解释了“固定-交换”求全排列的原理。


全排列原理

【ABC】按照当前顺序存在一个列表里面,我们来看一下结构:

第一层--- A和A自己换位,固定0位置的A;A和B换位,固定0位置的B;A和C换位置,固定0位置的C;
第二层第一子部分--- (0位A已经被固定)【ABC】从1位开始,B和B自己换位,固定1位置的B;(0位A已经被固定)【ABC】从1位开始,B和C换位,固定1位置的C;//输出ABC
第三层第二子部分--- (0位A已经被固定) (1位C已经被固定)【ABC】从2位开始,B和B自己换位,固定3位置的B;//输出ACB

可以看到,递归的入口在【换位】之后,被换到首位的元素将被固定,新的首位将会++,换位后再次被固定。
递归出口在,当首位编号和列表长度已经一样的时候。
下面为了方便理解,直接显式的给出了起始位置为0,结束位置为2。(对于【ABC】这样一个length为3的列表);

public static void main(String[] args){
  int[] array = new int[]{1,2,3};
  permute(array, 0,2);//input array; start position; end position
}

public static void permute(int[] given, int start, int end){
    if(start == end){//如果起始位子已经等于结束位置了,则打印当前列表结束当前递归方法
            for(int j : given){//for循环 按顺序打印当前列表
                  System.out.print(j);
                 }
            System.out.println(" ");     
        }
        else{//如果起始位置不等于结束位,则
            for(int i=start; i<=end ; i++){//从起始位置开始
                swap(given,i,start);//1.把当前位和起始位元素进行换位
                                    //得到的新given数列为下一层递归的输入
                permute(given,start+1,end);//进入下一层递归。
                                           //换位以后的新given为输入数列,
                                           //起始位置++(因为首位已经被固定住了),
                                           //结束位置不变
                swap(given,start,i);//递归的重点在于结束低一层回到上一层时
                                    //当层的given数列要和进入下层递归前保持一致
                                    //在执行上一句进入下层递归之前我们交换了元素
                                   //所以在上一句进入下层递归之后
                                  //我们需要把交换了的元素换回原样
                }
        }
  }

  public static void swap(int[] array, int s, int i){
    int t = array[s];
    array[s] = array[i];
    array[i] = t;
  }

写一下得到【BCA】这个结果的递归流程:

1|拿到原始输入【ABC】,起始位为0
2|for( 起位(0) to 结束位){
3|swap: 将起位(0)和1位交换得到【BAC】
4|---->permute: 进入下层递归,输入为【BAC】,新起始位为1
5|swap: 下层递归结束,将元素归位,当前given回到【ABC】
6|}
7|---->
1|----拿到输入【BAC】,起始位为1
2|----for(起始位(0) to 结束位){
3|----swap: 将起位(1)和2位交换得到【BCA】
4|----|---->permute: 进入下层递归,输入为【BCA】,新起始位为2
5|----|swap: 下层递归结束,将元素归位,当前given回到【BAC】
6|----|}
7|----|---->
1|----|----拿到输入【BCA】,新起始位为2
2|----|----起始位=结束位,结束当层递归,回到上一层。

你可能感兴趣的:(JAVA-给定个数对象的全排列原理)