美文网首页
JAVA-给定个数对象的全排列原理

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

作者: Kaidi_G | 来源:发表于2018-06-19 18:23 被阅读54次

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


    全排列原理

    【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-给定个数对象的全排列原理

          本文链接:https://www.haomeiwen.com/subject/xkfzeftx.html