• 全排列算法--递归实现(Java)


    求一个n阶行列式,一个比较简单的方法就是使用全排列的方法,那么简述以下全排列算法的递归实现。

    首先举一个简单的例子说明算法的原理,既然是递归,首先说明一下出口条件。以[1, 2]为例

    首先展示一下主要代码(完整代码在后面),然后简述

      //对数组array从索引为start到最后的元素进行全排列
    public void perm(int[]array,int start) { if(start==array.length) { //出口条件 for(int i=0;i<array.length;i++) { // this.result[row][i] = array[i]; System.out.print(array[i]+" "); } // System.out.print(++this.row+": "); // System.out.println("逆序数是:"+ this.against(array)); System.out.print(' '); } else { for(int i=start;i<array.length;i++) { swap(array,start,i); //交换数组array中索引为start与i的两个元素 perm(array,start+1); swap(array,start,i); } } }

    首先数组[1, 2]分析,在else的部分

    调用了swap(array, 0,0)然后调用perm(array, 1)

      调用swap(array, 1, 1)然后调用perm(array, 2),然后在if里面2 == 2成立,打印[1, 2]

      调用swap(array, 1,1)把之前交换的swap(array,1,1)复原,虽然看起来没有变化

    回到上一层

    调用swap(array, 0, 1) 然后调用perm(array, 1)

      调用swap(array, 1, 1)然后调用perm(array, 2),然后在if里面2 == 2成立,打印[2, 1]

      调用swap(array, 1,1)把之前交换的swap(array,1,1)复原,虽然看起来没有变化

    回到上一层

    跳出循环,程序结束。

    这就是对[1, 2]的全排列。

    那么放到一般情况,[1, 2, 3]呢?
    调用了swap(array, 0,0)然后调用perm(array, 1)
      然后对[2, 3]进行全排列,其中输出[1,2,3], [1, 3, 2]

    再次调用swap(array,0,0)复原

    调用了swap(array, 0,1)然后调用perm(array, 1)

      然后对[1,3]进行全排列,输出[2,1,3], [2,3,1]

    再次调用swap(array,0,1)复原

    调用了swap(array, 0,2)然后调用perm(array, 1)

      然后对[2,1]进行全排列,输出[3,2,1], [3,1,2]

    再次调用swap(array,0,2)复原

    更高阶的就是同理了!

    那么我们的代码如下:

    package matrix;
    
    import java.util.Arrays;
    
    public class Permutation {
    
        /**
         * author:ZhaoKe
         * college: CUST
         */
        //当前打印的第几个排列
        private int row = 0;
        //存储排列的结果
        private int[][] result;
        
        public Permutation(int[] array) {
            this.row = 0;
            this.result = new int[this.factor(array.length)][array.length];
        }
        
        public int[][] getResult() {
            return result;
        }
    
        //求数组a的逆序数
        public int against(int a[]) {
            int nn = 0;
            for (int i = 0; i < a.length-1; i++) {
                for (int j = i+1; j<a.length; j++) {
                    if (a[i] > a[j]) {
                        nn++;
                    }
                }
            }
            return nn;
        }
    
        //排列数
        public int factor(int a) {
            int r = 1;
            for (; a>=1; a--) {
                r *= a;
            }
            return r;
        }
    
        public void perm(int[]array,int start) {
            if(start==array.length) {
                System.out.print((this.row+1)+": ");
                for(int i=0;i<array.length;i++) {
                    this.result[row][i] = array[i];
                    System.out.print(array[i]+" ");
                }
                this.row++;
                System.out.println("逆序数是:"+ this.against(array));
                System.out.print('
    ');
            }
            else {
                for(int i=start;i<array.length;i++) {
                    swap(array,start,i);
                    perm(array,start+1);
                    swap(array,start,i);
                }
            }
        } 
        
        public void swap(int[] array,int s,int i) {
            int t=array[s];
            array[s]=array[i];
            array[i]=t;
        }
        
        public void printResult() {
            for (int i = 0; i < result.length; i++) {
                    System.out.println(Arrays.toString(this.result[i]));
            }
        }
        
        public static void main(String[] args) {
            int[] a = {1, 2, 3};
            Permutation p = new Permutation(a);
            p.perm(a,0);
            p.printResult();
        }
    }

     运行该程序结果如下:

    1: 1 2 3 逆序数是:0
    
    2: 1 3 2 逆序数是:1
    
    3: 2 1 3 逆序数是:1
    
    4: 2 3 1 逆序数是:2
    
    5: 3 2 1 逆序数是:3
    
    6: 3 1 2 逆序数是:2
    
    [1, 2, 3]
    [1, 3, 2]
    [2, 1, 3]
    [2, 3, 1]
    [3, 2, 1]
    [3, 1, 2]
    

      

  • 相关阅读:
    instancetype
    字典转模型
    类前缀
    当你学不进去的时候 不妨看看大脑是怎么想的
    当你学不进去的时候 不妨看看大脑是怎么想的
    你属于开源性格测试六大分类中的哪一类呢
    你属于开源性格测试六大分类中的哪一类呢
    程序员会被淘汰吗?
    程序员会被淘汰吗?
    Java基础学习总结(49)——Excel导入导出工具类
  • 原文地址:https://www.cnblogs.com/zhaoke271828/p/12530031.html
Copyright © 2020-2023  润新知