字典序全排列简单研究

最近看算法设计与分析基础这本书,里面讲到了一个字典序全排列问题,书中的方法是:
(1)从右至左扫描当前的一个排列,需找第一个连续的选择ai和ai+1,使得ai
(2)在尾部存在大于ai的最小数也就是min{aj | aj>ai, j>i},并将它放置在i位置上。
(3)从i+1到n的位置,以元素ai,ai+1,....an.的增序进行填充,其中放在位置i上的元素已经消去。
这个方法也就是字典序非递归法,更简单的描述是:
 一般而言,设P是[1,n]的一个全排列。
      P=P1P2…Pn=P1P2…Pj-1PjPj+1…Pk-1PkPk+1…Pn
    find:  j=max{i|Pi
             k=max{i|Pi>Pj}
      1,  对换Pj,Pk,
      2,  将Pj+1…Pk-1PjPk+1…Pn翻转
              P’= P1P2…Pj-1PkPn…Pk+1PjPk-1…Pj+1即P的下一个

确实很巧妙的算法了,算法复杂度为O(n*n!)
我自己也小试牛刀一把,实现了下字典序最基本的递归算法。思路图大致如下
即定义一个isUsed数组,标记1~n数是否使用,在定义一个arr数组,按从小到大顺序存放第 i 位应该存放的数字。当isUsed数组全部标记使用时,输出当前arr数组。
每次从小到大填充arr数组时,从小到大遍历isUsed数组,选出第一个未标记使用的数字,存放到arr数组,并标记isUsed使用,然后arr数组下一位数字的填充(递归)。
算法复杂度为O((n!)^2)
代码如下:
#include 

#define N_MAX 100

void fun(int N, int *isUsed, int k, int *arr)
{
	int i=0,j=0;
	static int num=0;
	for(i=0;i= (N-1))
		{
			printf("arr %d: ",++num);
			for(j=0;j

如参考1中所说,如果要提高性能,可采用并行计算 + nmap将文件映射到内存。

参考:【1】 字典序全排列生成算法提速
http://blog.csdn.net/pennyliang/article/details/5989555

【2】 字典序全排列算法研究
http://www.cnblogs.com/pmars/p/3458289.html

你可能感兴趣的:(算法)