Python 非递归方法的全排列
2018-01-30 22:24
267 查看
python
algorithm
全排列(Permutation)
排列(英语:Permutation)是将相异物件或符号根据确定的顺序重排。每个顺序都称作一个排列。例如,从一到六的数字有720种排列,对应于由这些数字组成的所有不重复亦不阙漏的序列,例如4, 5, 6, 1, 2, 3 与1, 3, 5, 2, 4, 6。【From Wikipedia】从n个相异元素中取出 k个元素,k个元素的排列数量为:
Pnk=n!(n−k)!Pkn=n!(n−k)!
其中P意为Permutation(排列),!表示阶乘运算。全排列而取k为n,则结果为n!。
全排列生成算法
字典序法
字典序,就是将元素按照字典的顺序(a-z, 1-9)进行排列。以字典的顺序作为比较的依据,可以比较出两个串的大小。比如 “1” < “13”<”14”<”153”, 就是按每个数字位逐个比较的结果。对于一个串“123456789”, 可以知道最小的串是“123456789”,而最大的串“987654321”。这样针对这个串以字典序法生成全排列生成全排列,就是依次生成“123456789”->“123456798”->……->”987654312”->”987654321”这样的串。字典序法要求这一个与下一个有尽可能长的共同前缀,也即变化限制在尽可能短的后缀上。邻位对换法
该算法由Johnson-Trotter首先提出,是一个能快速生成全排列的算法。它的下一个全排列总是上一个全排列对换某相邻两位得到的。如果已知n-1个元素的排列,将n插入到排列的不同位置,就得到了n个元素的排列。用这种方法可以产生出任意n个元素的排列。这个方法有一个缺点:为了产生n个元素的排列,我们必须知道并存储所有n-1个元素的排列,然后才能产生出所有n阶排列。递增进位制法
这个算法是基于序列的递增进位制数[3]。递增进位制数是指数字的进制随着位数的递增而递增。一般情况下,数字最右边的进制是2,次右边的进制是3,以此类推。n位递增进位制数一共包含n!个数字,所以它可以与全排列生成算法结合在一起。递减进位制法
该方法与递增进位制法的原理相似,不同的是它定义的“递减进位制数”是数字的进制随着位数的递增而递减。这种进制一般最左边的进制是2,次左边的进制是3。其余原理与递增进位制法基本相同。Python实现
字典序法非递归算法
设P是集合{1,2,……n-1,n}的一个全排列:P=P1P2……Pj-1PjPj+1……Pn(1≤P1,P2,……,Pn≤n-1)
1.从排列的右端开始,找出第一个比右边数字小的数字的序号j,即j=max{i|Pi<Pi+1,i>j}在Pj的右边的数字中,
找出所有比Pj大的数字中最小的数字Pk,即k=min{i|Pi>Pj,i>j}
2.交换Pi,Pk
3.再将排列右端的递减部分Pj+1Pj+2……Pn倒转,因为j右端的数字是降序,所以只需要其左边和右边的交换,直到中间,因此可以得到一个新的排列P’=P1P2……Pj-1PkPn……Pj+2Pj+1
代码
#!/usr/bin/env python2 # -*- coding: utf-8 -*- """ @author: gsharp """ def Swap(n,a,b): n[a],n = n[b],n[a] return None def Reverse(n,begin): if len(n) > begin: i = begin j = len(n)-1 while i < j: Swap(n,i,j) i += 1 j -= 1 return n def FindMin(n,i): j = len(n)-1 k = i + 1 while j > i: if n[j] > n[i] and n[j] < n[k]: k = j j -= 1 return k def Permut(n): count = 0 j = len(n) -1 if j < 1: return n else : print n count += 1 while j >= 1: i = j - 1 if n[i] < n [j] : k = FindMin(n,i) Swap (n,i,k) Reverse (n,j) j = len(n) - 1 count += 1 print n else : j -= 1 print count n =[1,2,3,4,5,6] Permut(n)
[b]注意:
1. 这里只能对于具有可比较值的列表排序,对于如【’~’,’!’,’@’,’#’】无法直接排序。
2. 初始序列必须为最小序列,否则无法列出全部排列。可先使用快速排序来排序后作为输入。
相关文章推荐
- python递归计算N!的方法
- Python利用递归和walk()遍历目录文件的方法示例
- Python多层嵌套list的递归处理方法(推荐)
- 用递归的方法实现全排列
- python 利用递归实现全排列
- 用递归的方法实现全排列
- 集合的全排列问题-递归实现方法
- 算法学习笔记7-非递归方法写一个全排列
- Python:斐波那契数列递归实现方法
- 全排列的两种常见方法(递归,STL)
- 使用递归方法实现全排列
- python基于右递归解决八皇后问题的方法
- 使用go和python递归删除.ds store文件的方法
- 全排列——递归方法
- 数组全排列的递归方法实现
- 通过python巧妙的递归获取文件夹中的文件/文件夹的方法
- 用Python递归解决阿拉伯数字转为中文财务数字格式的问题(2)--打开思路的一种方法
- python语言实现阶乘的两种方法---递归和迭代
- python非递归全排列实现方法
- 二分查找的递归方法python