JAVA用递归实现全排列算法的示例代码

所属分类: 软件编程 / java 阅读数: 60
收藏 0 赞 0 分享

求一个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('\n');
    }
    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('\n');
    }
    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]

以上就是JAVA用递归实现全排列算法的示例代码的详细内容,更多关于JAVA递归实现全排列的资料请关注脚本之家其它相关文章!

更多精彩内容其他人还在看

利用MultipartFile实现文件上传功能

这篇文章主要为大家详细介绍了利用MultipartFile实现文件上传功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Java编程实现NBA赛事接口调用实例代码

这篇文章主要介绍了Java编程实现NBA赛事接口调用实例代码,具有一定参考价值,需要的朋友可以了解下。
收藏 0 赞 0 分享

Java编程之双重循环打印图形

这篇文章主要介绍了Java编程之双重循环打印图形,属于Java编程基础练习部分,具有一定参考价值,需要的朋友可以了解下。
收藏 0 赞 0 分享

java基础学习JVM中GC的算法

这篇文章主要介绍了java基础学习JVM中GC的算法,通过图文加深对GC算法思路的理解。
收藏 0 赞 0 分享

Java编程Post数据请求和接收代码详解

这篇文章主要介绍了Java编程Post数据请求和接收代码详解,涉及enctype的三种编码,post与get等相关内容,具有一定参考价值,需要的朋友可以了解下。
收藏 0 赞 0 分享

Retrofit+Rxjava实现文件上传和下载功能

这篇文章主要介绍了Retrofit+Rxjava实现文件上传和下载功能,文中提到了单文件上传和多文件上传及相关参数的请求,需要的朋友参考下吧
收藏 0 赞 0 分享

Retrofit+Rxjava下载文件进度的实现

这篇文章主要介绍了Retrofit+Rxjava下载文件进度的实现,非常不错,具有参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

java检查服务器的连通两种方法代码分享

这篇文章主要介绍了java检查服务器的连通两种方法代码分享,涉及ping的介绍以及检查服务器连通的两种方法代码示例,具有一定参考价值,需要的朋友可以了解下。
收藏 0 赞 0 分享

Java/Android 获取网络重定向文件的真实URL的示例代码

本篇文章主要介绍了Java/Android 获取网络重定向文件的真实URL的示例代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

java并发编程之同步器代码示例

这篇文章主要介绍了java并发编程之同步器代码示例,分享了相关代码,具有一定参考价值,需要的朋友可以了解下。
收藏 0 赞 0 分享
查看更多