递归实现全排列问题
2017-09-23 13:20
211 查看
最近在上算法课,学到递归和分治策略总觉得有些难以理解……怎么说呢我总觉得递归的代码很简单,但是真正在看代码想象递归过程的时候想着想着就想不通了,准确来说自己确实不知道递归到哪个环节了并且这一层递归结束后到底该返回到哪里去……哇真的感觉要笨死==算法作业做到第二题就被卡住了,不知道该怎么写……舍友告诉我说这是一个全排列问题,我看了看代码想象着这个递归过程却一次又一次的懵逼:(老师知道也许会被气死毕竟上课讲过……百度了一下也和书上的代码差不多……后来看了一遍又一遍代码,我突然意识到,这是全排列???我一直将全排列和快速排序弄混了,所以我纠结了许久的为什么全排列里面没有比较大小再交换顺序的代码在这段程序里面是不可能存在的,尴尬……自己给自己挖了坑跳进去还出不来了……好了言归正传,还是来说一下递归解决全排列的问题吧。
设R={r1,r2,…,rn}是要进行全排列的n个元素,Ri=R-{ri}集合X中元素的全排列记为Perm(X)。R的全排列可归纳定义如下:
1.当n=1时,Perm(R)={r},其中r是集合R中唯一的元素。
2.当n>1时,Perm(R)由(r1)Perm(R1)、(r2)Perm(R2)、……、(rn)Perm(Rn)构成.
根据分治法的设计思想,将一个难以解决的大问题分割成一些小规模的相同问题,以便于各个击破分而治之。说的直白点,就是通过递归的方式把集合的规模逐步缩小。比如集合R={a,b,c,d},先固定a,递归求{b,c,d}的全排列,再固定b,递归求{c,d}的全排列,……以此类推,直到剩下最后一个字母,输出这段排列。为了方便理解这个问题,我画了一个图。
箭头后面就是每轮递归结束时输出的结果,下划线标注的则是每次固定的字母。固定b、c、d和上面的过程差不多我就省略了没写,不小心把集合的大括号写成了小括号懒得再写一次了就这样将就着看吧:)
该放代码了,我就上面的图写了一段程序。
设R={r1,r2,…,rn}是要进行全排列的n个元素,Ri=R-{ri}集合X中元素的全排列记为Perm(X)。R的全排列可归纳定义如下:
1.当n=1时,Perm(R)={r},其中r是集合R中唯一的元素。
2.当n>1时,Perm(R)由(r1)Perm(R1)、(r2)Perm(R2)、……、(rn)Perm(Rn)构成.
根据分治法的设计思想,将一个难以解决的大问题分割成一些小规模的相同问题,以便于各个击破分而治之。说的直白点,就是通过递归的方式把集合的规模逐步缩小。比如集合R={a,b,c,d},先固定a,递归求{b,c,d}的全排列,再固定b,递归求{c,d}的全排列,……以此类推,直到剩下最后一个字母,输出这段排列。为了方便理解这个问题,我画了一个图。
箭头后面就是每轮递归结束时输出的结果,下划线标注的则是每次固定的字母。固定b、c、d和上面的过程差不多我就省略了没写,不小心把集合的大括号写成了小括号懒得再写一次了就这样将就着看吧:)
该放代码了,我就上面的图写了一段程序。
#include <iostream> using namespace std; void perm(char list[],int k,int m) { //产生list[k:m]的全排列 if(k==m) { //只剩下一个元素 for(int i=0;i<=m;i++) cout<<list[i]; cout<<endl; } else //还有多个元素带排列,递归产生排列 { for(int i=k;i<=m;i++) { swap(list[k],list[i]); perm(list,k+1,m); swap(list[k],list[i]); } } } void swap(char a,char b) //交换 { char temp=a; a=b; b=temp; } int main() { char list[4]; cin>>list; cout<<endl; perm(list,0,3); return 0; }输入abcd,运行结果如下:
相关文章推荐
- 全排列问题算法实现--递归
- Java 非递归实现的排列组合中的平均分组问题
- 递归实现排列组合问题
- 多个数组间元素排列组合问题求解(Java实现) 标签: 递归排列组合循环
- 全排列算法递归及STL实现,八皇后问题
- 集合的全排列问题-递归实现方式的改进---旋转法
- 递归实现字母的排列问题
- 全排列问题 递归实现
- 全排列问题的递归、STL实现
- 递归实现排列组合问题
- 全排列问题递归实现
- 全排列问题算法分析与实现(递归、非递归)
- 货船装箱问题的递归和非递归实现
- 折半查找实现算法二(递归办法)PS:编译后有一个warning,但不影响结果,代码设计上应该还有些问题
- XSLT实现XML无极限树(精简版)[二] 解决没有递归出节点属性值总和的问题(JS实现)
- 动态规划之装配线问题(递归实现)
- 【自写】【求全排列】【新算法】【递归实现】
- 简单的[0/1]背包问题 分别用递归与非递归实现
- 0-1背包问题递归和非递归实现
- 常用算法的递归实现问题分析(针对《数据结构与程序设计》by Robert.L.Kruse)