方法1:
程序大致结构:
约定:pl[len] //pl 为最终放置结果的数组;len为数组的长度
ele为参与排列的个元素出现的个数
i为pl中下标
假设参与排列的元素有ABCD
run(ele,int i){
{
递归收敛判断;
收敛后进行处理;
}
//递归块1
{ 若元素A的个数不为0;
将元素A的个数减1;
run (ele,i+1);
将元素A的个数 加1;
}
//递归块2
{ 若元素B的个数不为0;
将元素B的个数减1;
run (ele,i+1);
将元素B的个数 加1;
}
//递归块3
{ 若元素C的个数不为0;
将元素C的个数减1;
run (ele,i+1);
将元素C的个数 加1;
}
......
/ /递归块n
{ 若元素M的个数不为0;
将元素M的个数减1;
run (ele,i+1);
将元素M的个数 加1;
}
}
注意:在递归块内,不应对所传入的参数进行改变;每个递归块所得到的原始参数应保持一致。
举例:ABCDEF进行排列
static int[] ele={1,1,1,1,1,1};//每个元素出现的个数
static int len=6;排列的长度
static char[] rst=new char[6];
static void run(int[] ele,int i){
if(i==len){
for(char c:rst)
System.out.print(c);
System.out.print('\n');
}
if(ele[0]!=0){
ele[0]--;// <span style="color:#ff0000;">对传入的参数改变了,所以必须在本块内进行恢复</span>
rst[i]='A';
run(ele,i+1);//<span style="color:#ff0000;">i本身没有改变
</span> ele[0]++;//<span style="color:#ff0000;">对参数进行恢复</span>。
}
if(ele[1]!=0){
ele[1]--;
rst[i]='B';
run(ele,i+1);
ele[1]++;
}
if(ele[2]!=0){
ele[2]--;
rst[i]='C';
run(ele,i+1);
ele[2]++;
}
if(ele[3]!=0){
ele[3]--;
rst[i]='D';
run(ele,i+1);
ele[3]++;
}
if(ele[4]!=0){
ele[4]--;
rst[i]='E';
run(ele,i+1);
ele[4]++;
}
if(ele[5]!=0){
ele[5]--;// 对传入的参数改变了,所以必须在本块内进行恢复
rst[i]='F';
run(ele,i+1);
ele[5]++;//对参数进行恢复。
}
}
方法2:( 优化方法1)
程序结构:
set 中存放全部复合类型ele
ele{
Type x;//参与排列的数据类型
int num ;//该元素可以出现的个数
}
len:存放排列的数组长度
参数说明:n为 集合set剩余n个元素中选择,实际没有参与运算,仅仅是为了增加程序的可读性。
i为存放排列的数组的下标
run(set,int n,int i){
if(i==len){
递归结束
} else{
for (Ele ele:set){
if(ele可用){
ele.num--;
run(set,n-1,i+1);
ele.num++;
}
}
}
}
实例:
1234 中任取3个元素全排列
public class Main {
static ArrayList<Ele> set =new ArrayList<Ele>();// 存放参与排列的元素的包装类型
static int[] rst=new int[3]; //存放排列
// <pre name="code" class="java"> //参与排列的元素的包装类
public static class Ele{ int num;//
参与排列的元素boolean slc;//用于控制该元素的个数,由于本例中个元素最多出现一次,故使用bool来控制 public Ele(int i, boolean b) { num=i; slc=b;// TODO Auto-generated constructor stub} }
//核心程序
static void selct(ArrayList<Ele> set,int n,int i){
if(n==0){//<span style="color:#ff0000;">此处完全可以换成i==len来判断</span>
for(int num:rst){
System.out.print(num);
}
System.out.println("");
}else{
for(Ele ele:set){
if(!ele.slc){
ele.slc=true;
rst[i]=ele.num;
<span style="font-family: Arial, Helvetica, sans-serif;">//从set中其他n-1个元素进行全排列,从排列的i+1号位置开始</span>
selct(set,n-1,i+1);
ele.slc=false;
}
}
}
}
public static void main(String[] args){
//为参与排列的元素赋值,这里共有4个元素1234
for(int i=1;i<5;i++) {
set.add(new Ele(i,false));
}
<pre name="code" class="java"> //从set中取3个元素进行全排列,从排列的0号位置开始
<span style="font-family: Arial, Helvetica, sans-serif;"> selct(set,3,0);</span>
}}