全排列算法--递归实现(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('\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
public class PaiLie { /** * @param args */ public static void main(String[] args) { PaiLie p=new Pai ...
- Java数据结构和算法 - 递归
三角数字 Q: 什么是三角数字? A: 据说一群在毕达哥拉斯领导下工作的古希腊的数学家,发现了在数学序列1,3,6,10,15,21,……中有一种奇特的联系.这个数列中的第N项是由第N-1项加N得到的 ...
- 获取所有组合算法、获取全排列算法(java)
转载声明:原文转自:http://www.cnblogs.com/xiezie/p/5574516.html 受到ACM1015的影响,个人感觉,有必要对统计学上的 全组合和全排列 进行一个简单的总结 ...
- 经典算法问题的java实现 (二)
原文地址: http://liuqing-2010-07.iteye.com/blog/1403190 1.数值转换(System Conversion) 1.1 r进制数 数N的r进制可以表 ...
- 全排列算法的JS实现
问题描述:给定一个字符串,输出该字符串所有排列的可能.如输入“abc”,输出“abc,acb,bca,bac,cab,cba”. 虽然原理很简单,然而我还是折腾了好一会才实现这个算法……这里主要记录的 ...
- 不会全排列算法(Javascript实现),我教你呀!
今天我很郁闷,在实验室凑合睡了一晚,准备白天大干一场,结果一整天就只做出了一道算法题.看来还是经验不足呀,同志仍需努力呀. 算法题目要求是这样的: Return the number of total ...
- 全排列问题(递归&非递归&STL函数)
问题描述: 打印输出1-9的所有全排序列,或者打印输出a-d的全排列. 思路分析: 将每个元素放到余下n-1个元素组成的队列最前方,然后对剩余元素进行全排列,依次递归下去. 比如:1 2 3 为例首先 ...
- Dijkstra算法求最短路径(java)(转)
原文链接:Dijkstra算法求最短路径(java) 任务描述:在一个无向图中,获取起始节点到所有其他节点的最短路径描述 Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到 ...
- 排序算法总结(基于Java实现)
前言 下面会讲到一些简单的排序算法(均基于java实现),并给出实现和效率分析. 使用的基类如下: 注意:抽象函数应为public的,我就不改代码了 public abstract class Sor ...
随机推荐
- JavaScript DOM三种创建元素的方式
三种创建元素的方式: document.write() element.innerHTML document.createElement() 初始HTML内容: <button>btn&l ...
- Java安全之Commons Collections1分析(二)
Java安全之Commons Collections1分析(二) 0x00 前言 续上篇文,继续调试cc链.在上篇文章调试的cc链其实并不是一个完整的链.只是使用了几个方法的的互相调用弹出一个计算器. ...
- EntityFramwork基础用法
一.EntityFramework(简称"EF")是什么? 在.NET3.5之前,我们经常编写ADO.NET代码或通过封装好的数据库访问层来与数据库进行交互,进行CRUD操作.这种 ...
- devops-jenkins-Pipeline基础语法
1. jenkins-Pipeline基础语法 1) jenkins-Pipeline总体介绍 • Pipeline,简而言之,就是一套运行与jenkins上的工作流框架,将原本独立运行于单个或多个 ...
- Oracle和MySql之间SQL区别(等效转换以及需要注意的问题)
本篇博文是Oracle和MySQL之间的等效SQL转换和不同,目前市面上没有转换两种SQL的工具,小编觉得以后也不一定会有,于是在业余时间整理了一下,如果有什么错误之处请留言告知,小编也是刚入门的小白 ...
- Sqlite嵌入式数据库讲解
在计算机系统中,保存数据的方式一般有两种:1. 普通文件方式2. 数据库方式 相比于普通文件方式,使用数据库来管理大批量数据具有更高的效率与安全性. 数据库系统一般由3个部分构成1. 数据库2. 数据 ...
- SpringBoot常见注解
0.前言 这篇文章介绍的 Spring/SpringBoot 常用注解基本已经涵盖你工作中遇到的大部分常用的场景.对于每一个注解我都说了具体用法,掌握搞懂,使用 SpringBoot 来开发项目基本没 ...
- day17 Pyhton学习 内置函数继续
1. locals 本地作用域/局部作用域 会随着位置的改变而改变 2.globals 全局作用域 永远不变,永远是全局 3.complex:复数 实数(有理数和无理数) 某一个数的平方是-1 ...
- Warning: Permanently added the RSA host key for IP address '52.74.223.119' to the list of known hosts.
如果出现这个问题,说明你的github缺少公钥 使用 ssh -T git@gtihub.com 去测试 1.生成密钥 ssh-keygen -t rsa -C "your name&quo ...
- python面试题-python相关
1. __new__.__init__区别,如何实现单例模式,有什么优点 __new__是一个静态方法,__init__是一个实例方法 __new__返回一个创建的实例,__init__什么都不返回 ...