采用分治方法对N个元素进行全排列计算

来源:互联网 发布:网络机柜照明灯 编辑:程序博客网 时间:2024/06/01 21:46

在进行全排列的每个元素中,首先选择一个元素出来,放在一个排列的最前面,把剩下的元素当做一个新的问题,进行全排列操作,在新的元素集合中再次选择一个元素,放在该排列的第二个位置,剩下的元素又是一个新的集合,依次执行同样的操作,直到剩余集合为空,一条排列完成。

同样的,完成第二条排列时,从上个集合中选择一个刚才没有选择的元素作为该条排列的第一个元素,同样的直到集合为空。当元素集合为空时都返回上一个集合。

例如:现有元素集合{a, b, c}

从中拿出一个元素作为该排列的第一个,拿出a,剩余元素集合为{b, c}

再从新的元素集合{b, c}中拿出一个元素b,得到新的集合{c}

再从新的集合{c}中拿出一个元素,这里只有一个元素了,所以只能拿c元素了

所以得到一条排列   a b c

由于c元素拿出来之后就没有元素了,所以只能返回上一个集合{b, c}

从{b, c}中拿出前面没有拿过的元素,因为刚才在{b, c}集合拿元素的时候,已经拿了b了,所以就不能拿b了,剩余只有c,得到新的集合{b}

再从新的集合{b}中拿出一个元素这里只有一个元素了,所以只能拿b元素了

  所以得到一条排列   a c b

由于b拿出来之后就没有元素了,所以只能返回上一个集合{b, c},此时{b,c}集合的元素都已经被拿过了,所以只有返回上一级集合{a,b, c}

在集合{a,b, c}中,a已经被拿过了,所以只能从b,c中选一个,顺便选一个都可以,这里我们选择b,得到新集合{a , c}

再从新的元素集合{a, c}中拿出一个元素a,得到新的集合{c}

再从新的集合{c}中拿出一个元素,这里只有一个元素了,所以只能拿c元素了

所以得到一条排列   b a c

由于c元素拿出来之后就没有元素了,所以只能返回上一个集合{a, c}

从{a, c}中拿出前面没有拿过的元素,因为刚才在{a, c}集合拿元素的时候,已经拿了a了,所以就不能拿a了,剩余只有c,得到新的集合{a}

再从新的集合{a}中拿出一个元素这里只有一个元素了,所以只能拿a元素了

  所以得到一条排列   b c a

由于a拿出来之后就没有元素了,所以只能返回上一个集合{a, c},此时{a,c}集合的元素都已经被拿过了,所以只有返回上一级集合{a,b, c}

在集合{a,b, c}中,a, b已经被拿过了,所以只能选c,得到新集合{a , b}

再从新的元素集合{a, b}中拿出一个元素a,得到新的集合{b}

再从新的集合{b}中拿出一个元素,这里只有一个元素了,所以只能拿b元素了

所以得到一条排列   c a b

由于b元素拿出来之后就没有元素了,所以只能返回上一个集合{a, b}

从{a, b}中拿出前面没有拿过的元素,因为刚才在{a, b}集合拿元素的时候,已经拿了a了,所以就不能拿a了,剩余只有b,得到新的集合{a}

再从新的集合{a}中拿出一个元素这里只有一个元素了,所以只能拿a元素了

  所以得到一条排列   c b a

由于a拿出来之后就没有元素了,所以只能返回上一个集合{a, b},此时{a,b}集合的元素都已经被拿过了,所以只有返回上一级集合{a,b, c},

而集合{a, b, c}元素都已经被过了,所以全排列完成。

附算法代码:

public class Permutations {//交换字符public void exchange(char[] cs, int l1, int l2){char tmp = cs[l1];cs[l1] = cs[l2];cs[l2] = tmp;}        //全排列,l为新集合的开始位置public void permutations(char[] cs, int l){if(cs.length-1 == l){System.out.println(cs);//打印结果}for(int i=l; i<cs.length; i++){exchange(cs, l, i);permutations(cs, l+1);exchange(cs, l, i);}}//测试代码public static void main(String[] args) {char[] cs = "abcd".toCharArray();Permutations p = new Permutations();p.permutations(cs, 0);}}



0 0
原创粉丝点击