C++输出全排列递归算法详细解释

中心思想:

设R={r1,r2,…,rn}是要进行排列的n个元素,Ri=R-{ri}.

Perm(X)表示在全排列Perm(X)的每一个排列前加上前缀ri得到的排列。

(1)当n=1时,Perm(R)=(r),其中r是集合R中唯一的元素;

(2)当n>1时,Perm(R)可由(r1)+Perm(R1),(r2)+Perm(R2),…,(rn)+Perm(Rn)构成。

那么具体程序要怎么实现呢?我们来个实际的例子,假设有一数列1,2,3,4

那么1,2,3,4的全排列

perm({1,2,3,4})=1perm({2,3,4})+2perm({1,3,4})+3perm({1,2,4})+4perm(1,2,3)

那么我们只要将每个数,与第一个数交换不就可以得到下一个序列了吗?

比如{1,2,3,4}第一个与第二个数交换,那么不就得到2 {1,3,4}了,接下来我们用一个实际的例子说明该程序是怎样运行的

具体算法流程:

数列:{1,2,3} 第一个与第一个交换

可以得到1 {2,3} 将序列{2,3}放进perm函数递归,然后

——递归{2,3}

数列{2,3}第一个与第一个交换

得到2{3} ,输出1,2,3 (此时low=high,因为序列{3}只有一位数,因此输出列表list)

数列{2,3}第一个与第一个交换回来,结果仍然是{2,3}

数列{2,3}第一个与第二个交换

得到3{2},输出1,3,2

{3,2}又第一个与第二个交换回来,变回{2,3}

—–{2,3}递归完毕序列恢复原状{1,2,3}

数列:{1,2,3} 第一个与第二个交换

可以得到2,{1,3}

——递归{1,3}

数列{1,3}第一个与第一个交换

得到1{3} ,输出2,1,3

数列{1,3}第一个与第一个交换回来,结果仍然是{1,3}

数列{1,3}第一个与第二个交换

得到3{1},输出2,3,1

{3,1}又第一个与第二个交换回来,变回{1,3}

—–{1,3}递归完毕

序列{2,1,3}第一个与第二个交换

序列恢复原状{1,2,3}

数列:{1,2,3} 第一个与第三个交换

可以得到3,{1,2}

——递归{1,2}

数列{1,2}第一个与第一个交换

得到1{2} ,输出3,1,2

数列{1,2}第一个与第一个交换回来,结果仍然是{1,2}

数列{1,2}第一个与第二个交换

得到2{1},输出3,2,1

{2,1}又第一个与第二个交换回来,变回{1,2}

—–{1,2}递归完毕

序列{3,1,2}第一个与第二个交换

序列恢复原状{1,2,3}

算法可以简单地写作

perm({1,2,3})=1perm({2,3})+2perm({1,3})+3perm({1,2})

perm({2,3})=2perm({3})+3perm({2})

perm({1,3})=1perm({3})+3perm({1})

perm({1,2})=1perm({2})+2perm({1})

c++代码:

#include <iostream>
using namespace std;
void swap(int &a,int &b){
    int temp=a;
    a=b;
    b=temp;
}
void perm(int list[],int low,int high){
    if(low==high){   //当low==high时,此时list就是其中一个排列,输出list
        for(int i=0;i<=low;i++)
            cout<<list[i];
        cout<<endl;
    }else{
        for(int i=low;i<=high;i++){//每个元素与第一个元素交换
            swap(list[i],list[low]);
            perm(list,low+1,high); //交换后,得到子序列,用函数perm得到子序列的全排列
            swap(list[i],list[low]);//最后,将元素交换回来,复原,然后交换另一个元素
        }
    }
}
int main()
{

int list[]={1,2,3};
perm(list,0,2);
return 0;
}

程序结果:

123
132
213
231
321
312
时间: 2024-10-13 09:34:54

C++输出全排列递归算法详细解释的相关文章

Sed命令的使用详细解释

Sed命令的使用详细解释 一:sed命令的简介 sed是一种在线编辑器,它一次处理一行内容.处理时,把当前处理的行存储在临时缓冲区中,称为"模式空间"(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕.接着处理下一行,这样不断重复,直到文件末尾.文件内容并没有改变,除非你使用重定向存储输出.Sed主要用来自动编辑一个或多个文件:简化对文件的反复操作:编写转换程序等.     二:Sed的用法格式 Sed [options] 'scri

设计模式 - 迭代模式(iterator pattern) Java 迭代器(Iterator) 详细解释

迭代模式(iterator pattern) Java 迭代器(Iterator) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 參考迭代器模式(iterator pattern): http://blog.csdn.net/caroline_wendy/article/details/35254643 Java的标准库(util)中包括迭代器接口(iterator interface), import java.util.Iterator; 继承

C语言 - 结构体(struct)比特字段(:) 详细解释

结构体(struct)比特字段(:) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26722511 结构体(struct)能够使用位字段(:), 节省空间, 例如以下面代码, 结构体a中的, 第一个变量x占用1个字符, y占用2个字符, z占用33个字符(越界); 可是sizeof()会自己主动补齐, 如x+y一共占用4个字节, z占用8个字节, 所以结构体占用12个字节; 当使用加法运算时, 会初始化为0; 代码

cmd批处理转义字符%的详细解释

cmd批处理转义字符%的详细解释 在命令行中使用for时不需要双%,这源于命令解释器对命令行与批处理的处理方式不同. 1.%是个ESCAPE字符,通常将之译为转义字符,但也有更形象的译名脱逸字符.逃逸字符等.也就是说%不仅仅将与其相关的特定字符串转义并替换为特定字符串,而且自身也会被“脱逸”.而且类似于C语言中的转义字符"\",双%会转义并脱逸为单%,四%则脱为双%. 2.for本身是一个特殊的命令,类似于一个特化的命令解释器,因为它的功能实现需要执行多条语句,因此它必须也具有对命令行

详细解释 使用FileReference类加载和保存本地文件

一般而言,用户不希望web浏览器中运行的应用程序访问电脑硬盘里的文件.然而,随着基于浏览器(browser-based)的富因特网应用程序的增多,一些应用程序迫切需要访问用户所选择的文件,或者将文件保存到用户所选择的位置.支持FileReference类的Adobe Flash Player版本允许ActionScript应用程序将用户所选择的文件上传到服务器,或者从服务器下载文件到用户所选择的位置.然而,在Flash Player 10之前的版本中,除非您先将数据传送到服务器,否则无法在应用程

linux之ss命令详细解释

linux之ss命令详细解释 ss是Socket Statistics的缩写.顾名思义,ss命令可以用来获取socket统计信息,它可以显示和netstat类似的内容.但ss的优势在于它能够显示更多更详细的有关TCP和连接状态的信息,而且比netstat更快速更高效. 当服务器的socket连接数量变得非常大时,无论是使用netstat命令还是直接cat /proc/net/tcp,执行速度都会很慢.可能你不会有切身的感受,但请相信我,当服务器维持的连接达到上万个的时候,使用netstat等于浪

hdu1113 Word Amalgamation(超详细解释--map和string的运用)

转载请注明出处:http://blog.csdn.net/u012860063天资 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1113 来吧!!欢迎"热爱编程"的同学报考杭电,期待你加入"杭电ACM集训队"! 7月22-8月21多校联合训练期间,会根据实际负载关闭部分模块,若有不便,请谅解~ Word Amalgamation Time Limit: 2000/1000 MS (Java/Others)    Me

SSM:spring+springmvc+mybatis框架中的XML配置文件功能详细解释

SSM:spring+springmvc+mybatis框架中的XML配置文件功能详细解释 2016-04-14 23:40 13030人阅读 评论(2) 收藏 举报 分类: SSM(7) 这几天一直在整合SSM框架,虽然网上有很多已经整合好的,但是对于里面的配置文件并没有进行过多的说明,很多人知其然不知其所以然,经过几天的搜索和整理,今天总算对其中的XML配置文件有了一定的了解,所以拿出来一起分享一下,希望有不足的地方大家批评指正~~~ 首先   这篇文章暂时只对框架中所要用到的配置文件进行解

C语言scanf函数详细解释(转)

函数名: scanf 功 能: 执行格式化输入 用 法: int scanf(char *format[,argument,...]); scanf()函数是通用终端格式化输入函数,它从标准输入设备(键盘) 读取输入的信息.可以读入任何固有类型的数据并自动把数值变换成适当的机内格式. 其调用格式为:      scanf("<格式化字符串>",<地址表>); scanf()函数返回成功赋值的数据项数,出错时则返回EOF. 其控制串由三类字符构成: 1.格式化说明