求数组的全排列的非递归算法

求全排列一共有四种方法,字典序法,递增进位制数法,递减进位制数法,邻位对换法.我在这里讲最简单的字典序法.
这个生成法要求传进来的序列必须已经按从小到大人规律排过序.否则它不能生成正确的全排列.至于为什么用这个方法就可以生成全排列,我的知识有限,证明不了,只有拿来用了再说.
假定序列为a1,a2.... an (n > 0) ,如123456789,它从123456789开始,一直到987654321结束,中间有n个值,寻找这n个值需要做n步下面的操作:

1.找出比右边数字小的第一个数 找到这个数后,把它的位置记下来.设这个位置为pos_left;如果找不到,就说明排列完成了.
2.从右到左寻找第一个大于pos_left所在值的数,设为pos_right.
3.交换a[pos_left]与a[pos_right]的值.
4.逆转a[pos_left+1]到a[n]之间的值.
到此,寻找一个排列的步骤完成.

来个例子吧, 123, 做第1步,找到2比3小.pos_left = 2. 再做第2步,找到3比2大. pos_right = 3.然后做第3步,交换,得到 132 , 又因为pos_left后只有一个数,所以不用做逆转了.
这个太短了,干脆来个长点的 124653, 第1步找到4, pos_left = 3, 第2步找到5, pos_right = 5.然后交换得到125643, 再逆转得到125346, 从而得到新的排列.然后再对这个排列做上面4步,求出下一个排列....直到最后最后没有新排列可求出来.
java 代码
 
  1. //here a permutation is a reordering of  
  2. //objects up to isomorphism  
  3. public boolean nextPermutation(int[] arr) {  
  4.   int last = Integer.MIN_VALUE;  
  5.   int n = arr.length;  
  6.   int p = n-1;  
  7.   for (;p>=0;p--) {  
  8.     if (arr[p]<last) {  
  9.       for (int j = n-1; j > p; j--) {  
  10.         if (arr[j]>arr[p]) {  
  11.           swap(arr,p,j);  
  12.           reverse(arr,p+1,n);  
  13.           return true;  
  14.         }  
  15.       }  
  16.       return false;  
  17.     }  
  18.     last = arr[p];  
  19.   }  
  20.   for (int i = 0; i < n; i++) arr[i]=i;  
  21.   return false;  
  22. }  
  23. public void swap(int[] arr, int ind1, int ind2) {  
  24.   int t = arr[ind1];  
  25.   arr[ind1] = arr[ind2];  
  26.   arr[ind2] = t;  
  27. }  
  28. public void reverse(int[] arr, int ind1, int ind2) {  
  29.   if (ind2<=ind1) return;  
  30.   for (int i = 0; i < (ind2-ind1)/2; i++) {  
  31.     swap(arr,ind1+i,ind2-1-(i));  
  32.   }  
  33. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值