求一个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)的更多相关文章

  1. 数列全排列问题----递归实现--JAVA

    public class PaiLie { /** * @param args */ public static void main(String[] args) { PaiLie p=new Pai ...

  2. Java数据结构和算法 - 递归

    三角数字 Q: 什么是三角数字? A: 据说一群在毕达哥拉斯领导下工作的古希腊的数学家,发现了在数学序列1,3,6,10,15,21,……中有一种奇特的联系.这个数列中的第N项是由第N-1项加N得到的 ...

  3. 获取所有组合算法、获取全排列算法(java)

    转载声明:原文转自:http://www.cnblogs.com/xiezie/p/5574516.html 受到ACM1015的影响,个人感觉,有必要对统计学上的 全组合和全排列 进行一个简单的总结 ...

  4. 经典算法问题的java实现 (二)

    原文地址: http://liuqing-2010-07.iteye.com/blog/1403190   1.数值转换(System Conversion) 1.1 r进制数   数N的r进制可以表 ...

  5. 全排列算法的JS实现

    问题描述:给定一个字符串,输出该字符串所有排列的可能.如输入“abc”,输出“abc,acb,bca,bac,cab,cba”. 虽然原理很简单,然而我还是折腾了好一会才实现这个算法……这里主要记录的 ...

  6. 不会全排列算法(Javascript实现),我教你呀!

    今天我很郁闷,在实验室凑合睡了一晚,准备白天大干一场,结果一整天就只做出了一道算法题.看来还是经验不足呀,同志仍需努力呀. 算法题目要求是这样的: Return the number of total ...

  7. 全排列问题(递归&非递归&STL函数)

    问题描述: 打印输出1-9的所有全排序列,或者打印输出a-d的全排列. 思路分析: 将每个元素放到余下n-1个元素组成的队列最前方,然后对剩余元素进行全排列,依次递归下去. 比如:1 2 3 为例首先 ...

  8. Dijkstra算法求最短路径(java)(转)

    原文链接:Dijkstra算法求最短路径(java) 任务描述:在一个无向图中,获取起始节点到所有其他节点的最短路径描述 Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到 ...

  9. 排序算法总结(基于Java实现)

    前言 下面会讲到一些简单的排序算法(均基于java实现),并给出实现和效率分析. 使用的基类如下: 注意:抽象函数应为public的,我就不改代码了 public abstract class Sor ...

随机推荐

  1. 第一次面试linux后台岗位

    今天给大家分享前段时间面试linux后台的面试题目,我从里面挑了几道大家比较陌生的题目,而且要那种手写代码的题目,这方面肯定很多人在实际面试时最怕的题目! 1.请说出如何用tcp服务实现文件的断点续传 ...

  2. Arduino重置-复位问题

    转自: https://blog.csdn.net/y511374875/article/details/77845240 三种方式手动重启Arduino 1.Arduino板上重新编写代码时,Ard ...

  3. 【题解】小M的作物

    题目戳我 \(\text{Solution:}\) 这题要求最大收获,可以转化为所有可能的收益减去最小割. 单个点很好连边 \((S\to pos\to T),\) 问题在于如何处理组合的点. 观察到 ...

  4. IO那些事

    IO(Input\Output): 即输入输出,通常指数据在存储器(内部和外部)或其他周边设备之间的输入和输出,是信息处理系统(例如计算机)与外部世界(可能是人类或另一信息处理系统)之间的通信.说的简 ...

  5. 用Docker容器安装Jenkins

    先安装Docker 可以参考我的上一篇文章 链接 拉取Jenkins最新镜像,可跟版本号 不跟默认拉取最新镜像 docker pull jenkins/jenkins 创建JenKins的工作目录 m ...

  6. 【暑假集训】HZOI2019 Luogu P1006 传纸条 二三四维解法

    写三次丢失两次,我谔谔,以后再不在博客园先保存我就去死 题目内容 洛谷链接 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学被安排坐成一个\(m\)行.\(n\ ...

  7. js拖拽上传 文件上传之拖拽上传

    由于项目需要上传文件到服务器,于是便在文件上传的基础上增加了拖拽上传.拖拽上传当然属于文件上传的一部分,只不过在文件上传的基础上增加了拖拽的界面,主要在于前台的交互, 从拖拽的文件中获取文件列表然后调 ...

  8. spring boot:spring security用mysql数据库实现RBAC权限管理(spring boot 2.3.1)

    一,用数据库实现权限管理要注意哪些环节? 1,需要生成spring security中user类的派生类,用来保存用户id和昵称等信息, 避免页面上显示用户昵称时需要查数据库 2,如果需要在页面上显示 ...

  9. ReSharper 注册码

    用户名:ronle 注册码:ZoJzmeVBoAv9Sskw76emgksMMFiLn4NM 原文地址:http://hi.baidu.com/ronle/item/a509b5f7b851971be ...

  10. 第三十四章 Linux常规练习题(一)参考答案

    一.练习题一 1.超级用户(管理员用户)提示符是___#_,普通用户提示符是___$_. 2.linux关机重启的命令有哪些 ? 关机命令 重启命令 shutdown -h now shutdown ...