【转】全排列算法非递归实现和递归实现
2014-02-27 11:28
225 查看
来源:http://blog.csdn.net/e3399/article/details/7543861
(一)递归的全排列算法
(A、B、C、D)的全排列为
1、A后面跟(B、C、D)的全排列
2、B后面跟(A、C、D)的全排列
3、C后面跟(A、B、D)的全排列
4、D后面跟(A、B、C)的全排列
而对1中的(B、C、D)照样可以按照上面的形式进行分解。
View Code
下面的分析来自C语言程序设计-顾志华:(page251)
对一组数穷尽所有排列,还有更好的方法。将一个排列看成一个长整数,则每个排列对应一个不同的长整数,所有可能的排列对应着一组有限的整数。将这组整数按从小到大的顺序排成一个数列,从对应最小的整数开始,按数列的递增顺序顺序逐一列举每个排列对应的每一个整数,这能更有效地完成排列的穷举。从一个排列找出对应数列的下一个排列可在当前排列的基础上作部分调整来实现。倘若当前排列为1、2、4、8、7、6、5、3,并令其对应的长整数为12487653。要寻找比长整数12487653更大的排列,可从该排列的最后一个数字顺序向前逐位考察,当发现排列中的某个数字比前一个数字大时,如本例中的8比它的前一个数字4大,这说明还有对应更大整数的排列。但为了顺序从小到大列举出所有的排列,不能立即调整的太大,如本例中将数字8与4交换得到的序列12847653就不是排列12487653的下一个序列。为得到排列12487653的下一个排列,应从已考察过的那部分数字中选出比数字4大,但又是它们中最小的那一个数字,比如数字5,该数字也是从后向前考察过程中第一个比4大的数字。5与4交换后,得到排列12587643,在前面数字1、2、5固定的情况下,还应选择对应最小整数的那个序列。为此还需将后面那部分数字的排列顺序颠倒,如将数字8、7、6、4、3的顺序颠倒,得到排列1、2、5、3、4、6、7、8,这才是排列1、2、4、8、7、6、5、3的下一个排列。
(一)递归的全排列算法
(A、B、C、D)的全排列为
1、A后面跟(B、C、D)的全排列
2、B后面跟(A、C、D)的全排列
3、C后面跟(A、B、D)的全排列
4、D后面跟(A、B、C)的全排列
而对1中的(B、C、D)照样可以按照上面的形式进行分解。
#include "iostream" #include "algorithm" using namespace std; void permutation(int* a,int length) { int i,flag; sort(a,a+length); do { for(i=0;i<length;i++) { if(a[i]==3) flag=1; else if(a[i]==4) //如果3在4的左边,执行完代码,flag就是2 flag=2; } if(flag==1) //如果4在3的左边,执行完代码,flag就是1 { for(i=0;i<length;i++) cout<<a[i]; cout<<endl; } }while(next_permutation(a,a+length)); } int main(void) { int i,a[5]; for(i=0;i<5;i++) a[i]=i+1; printf("%d以内所有4在3左边的全排列结果为:\n",i); permutation(a,5); system("pause"); return 0; }
View Code
下面的分析来自C语言程序设计-顾志华:(page251)
对一组数穷尽所有排列,还有更好的方法。将一个排列看成一个长整数,则每个排列对应一个不同的长整数,所有可能的排列对应着一组有限的整数。将这组整数按从小到大的顺序排成一个数列,从对应最小的整数开始,按数列的递增顺序顺序逐一列举每个排列对应的每一个整数,这能更有效地完成排列的穷举。从一个排列找出对应数列的下一个排列可在当前排列的基础上作部分调整来实现。倘若当前排列为1、2、4、8、7、6、5、3,并令其对应的长整数为12487653。要寻找比长整数12487653更大的排列,可从该排列的最后一个数字顺序向前逐位考察,当发现排列中的某个数字比前一个数字大时,如本例中的8比它的前一个数字4大,这说明还有对应更大整数的排列。但为了顺序从小到大列举出所有的排列,不能立即调整的太大,如本例中将数字8与4交换得到的序列12847653就不是排列12487653的下一个序列。为得到排列12487653的下一个排列,应从已考察过的那部分数字中选出比数字4大,但又是它们中最小的那一个数字,比如数字5,该数字也是从后向前考察过程中第一个比4大的数字。5与4交换后,得到排列12587643,在前面数字1、2、5固定的情况下,还应选择对应最小整数的那个序列。为此还需将后面那部分数字的排列顺序颠倒,如将数字8、7、6、4、3的顺序颠倒,得到排列1、2、5、3、4、6、7、8,这才是排列1、2、4、8、7、6、5、3的下一个排列。
相关文章推荐
- 全排列算法的递归思想及实现
- 全排列算法递归实现 C++
- 全排列算法的非递归实现与递归实现的方法(C++)
- 递归实现的全排列算法
- LeetCode:Permutations(全排列算法的递归与非递归实现)
- 全排列算法非递归实现和递归实现
- 全排列算法的递归与非递归实现
- 全排列算法的递归实现
- 全排列算法-递归与字典序的实现方法(Java)
- 全排列算法的非递归实现
- 全排列算法的递归与非递归实现
- 全排列算法(字典序,递归实现)
- 全排列算法的递归与非递归实现
- 递归实现全排列算法
- 全排列算法非递归实现和递归实现
- 全排列算法【非递归活动数实现】
- 全排列算法(递归实现) 组合算法(递归,位运算实现)
- C# 遍历文件夹非递归实现(采用队列的广度优先算法)(转)
- 合并两个排序的链表---递归实现
- 递归实现进制转换