【题目】
给出一个集合{1,2,3},求解该集合的全排列并打印。
全排列问题的递归算法(Perm)
【算法思想】
设R={r1,r2,…,rn}是要进行排列的n个元素,Ri=R{ri}。
集合X中元素的全排列记为Perm(X)。
(ri)Perm(X)表示在全排列Perm(X)的每一个排列前加上前缀得到的排列。
R的全排列可归纳定义如下:
当n=1时,Perm(R)=(r),其中r是集合R中唯一的元素;
当n>1时,Perm(R)由(r1)Perm(R1),(r2)Perm(R2),…,(rn)Perm(Rn)构成。
【算法解读】
由Perm(X)=(r1)Perm(R1),(r2)Perm(R2),…,(rn)Perm(Rn)
一直向下分解(即不断化简Perm(R1),Perm(R2),…,Perm(Rn))直到n=1,
化到R为Perm(R)中唯一的元素。
规律:化简的过程即模拟了我们不断控制位置不变的元素变多的排列规则,也即使得能够自由排列的元素个数越来越小的过程。
【算法排列图解】以{1,2,3}为例

以上即是以算法的角度理解,略带晦涩,看后让人不容易想象到代码怎么写,我们可以换个角度理解:
【我们的思路】

从上图我们可以看出一切的精髓在于这条蓝线的移动以及移动区,非移动区
那么,要怎样才能使得蓝线移动呢???
我们发现,要点在于:
(1)边界元素的位置,也即第一个可以任意排序的元素的位置。
(2)移动区和非移动区暗示着我们会有一对以上的坐标变量
对于{1,2,3}的第一个分支来说,这个元素为1.
那么,我们给他注明下标:

这时,我们有一个问题:如何能让上图的1跑到非移动区呢???
要点在于:一开始让i与k指向相同的元素,依次让i指向的元素与k指向的元素交换位置,然后i指向下一个元素,k指向元素再与之交换。我们进行交换操作的范围就是在移动区内,随着逐层递归进行,移动区元素个数逐渐为0,即i==j,这时,我们再将非移动区的元素打印出来,这样就逐渐实现了递归遍历。

代码如下:

//交换元素位置函数
void Swap(int &a, int &b)
{int t = a;a = b;b = t;
}
void Perm(int *br, int i, int j)
{if (i == j){for (int m = 0; m <= i; ++m){cout << br[m] << " ";}cout << endl;}else{for (int k = i; k <= j; ++k){Swap(br[i], br[k]);Perm(br, i + 1, j);//递归回来时还原到本层的初始模样,//以便于下一次i++继续做递归时出发点是一样的。Swap(br[i], br[k]);}}
}
int main()
{int ar[] = { 1,2,3 };Perm(ar, 0, 2);return 0;
}

当我们递归到底之后,在返回过程中,还需要把元素位置还原。以便以相同的出发点向不同方向递归。
以上分析可以帮助理解Perm算法的思想,一句简单的结题口诀就是:
在递归的过程中将整组数中的所有的数分别与第一个数交换,这样就总是在处理后n-1个数的全排列,直到n=0。

算法学习之:全排列问题的递归算法(Perm)相关推荐

  1. 【算法导论06】递归算法-perm算法

    06递归算法-perm算法 问题描述: 给定一个含有n个数字的序列,设计算法对该序列进行全排列. 思路分析: 对n个数字序列进行全排列,最简单的思考方式是将n个数字依次作为序列的开头,得到n个n维序列 ...

  2. 算法学习——求有重复元素的全排列(递归)

    算法学习--求有重复元素的全排列(递归) 思路:看到这个题目首先能想到的一点就是:①我们要求元素的所有全排列②我们要对求出的全排列去重 第一步:求全排列,这里先讨论对不含重复元素的数组元素进行全排列, ...

  3. 计算机专业考研复试上机算法学习

    计算机专业考研复试上机算法学习 这篇博客是博主在准备可能到来的线下上机复试基于王道机试指南的学习,将各道习题链接和代码记录下来,这篇博客权且当个记录. 文章目录 计算机专业考研复试上机算法学习 1.S ...

  4. 计算机考研复试上机算法学习

    计算机考研复试上机算法学习 这篇博客是博主在准备可能到来的线下上机复试基于王道机试指南的学习,将各道习题链接和代码记录下来,这篇博客权且当个记录. 文章目录 计算机考研复试上机算法学习 1.STL容器 ...

  5. 原创 | 初学者友好!最全算法学习资源汇总(附链接)

    在计算机发展飞速的今天,也许有人会问,"今天计算机这么快,算法还重要吗?"其实永远不会有太快的计算机,因为我们总会想出新的应用.虽然在摩尔定律的作用下,计算机的计算能力每年都在飞快 ...

  6. java 全排列非递归算法_全排列的非递归算法 - osc_ivkc73ze的个人空间 - OSCHINA - 中文开源技术交流社区...

    1.全排列的定义和公式: 从n个数中选取m(m<=n)个数按照一定的顺序进行排成一个列,叫作从n个元素中取m个元素的一个排列.由排列的定义,显然不同的顺序是一个不同的排列.从n个元素中取m个元素 ...

  7. 令人拍案叫绝的算法学习网站新手算法入门到精通,算法面试冲刺资料这里都有

    (9月已更)学算法认准这6个网站就够了! 写在前面:作为ACM铜牌选手,从FB到腾讯,从事算法&java岗位工作也是5年有余.在工作中接触到了很多同学,在算法学习和算法面试这件事上我还是很有发 ...

  8. 算法学习之道,应有三重境界

    https://www.toutiao.com/a6712297555167805966/ 王国维先生在<人间词话>中写道:古今之成大事业.大学问者,必经过三种境界:"昨夜西风凋 ...

  9. cart算法 java_CART算法学习及实现

    CART算法学习及实现 作者:大卡卡   撰写时间:2011.9.29 1.算法介绍 分类回归树算法:CART(Classification And Regression Tree)算法采用一种二分递 ...

最新文章

  1. 一文快速入门分库分表中间件 Sharding-JDBC
  2. UA MATH564 概率论I 求离散型随机变量的分布1
  3. war 发布后页面不更新_一文看懂tomcat8如何配置web页面管理
  4. 《c语言从入门到精通》看书笔记——第9章 函数
  5. java选择题多选题系统小程序_单选题与多选题判断得分(自动考试小程序,入门级)...
  6. 把svg图标制作成字体图标_让我们用SVG符号和CSS变量制作彩色图标
  7. hihoCoder1690 (动态规划)
  8. Windows 10 JDK安装及环境配置(vim+gcc)
  9. python如何去某一列的元素
  10. Nginx(1)— Nginx工作原理
  11. Python sklearn 实现过采样和欠采样
  12. python学生教务管理系统
  13. 使用HTML制作网页
  14. 再谈微软复兴,纳德拉与库克、马斯克、皮查伊在管理上有什么不同
  15. H5小游戏开发多少钱
  16. oracle ndb,NDB语法 - ivaneeo's blog - BlogJava
  17. CRC循环冗余校验码总结
  18. 计算机 无法进入pe,电脑无法进入pe系统_电脑无法进入pe界面
  19. C/C++黑魔法-隐含的this指针
  20. 第72届英国影艺学院电影奖9日公布入围名单

热门文章

  1. 浅谈chatGPT——新必应(bing)版本
  2. linux ping不通自动关机脚本,服务器断电自动关机bat脚本
  3. Redis总结:缓存雪崩、缓存击穿、缓存穿透与缓存预热、缓存降级
  4. 不需要密码卸载Symantec Endpoint Protection
  5. 简单的图像几何校正实践
  6. Fedora 14 root权限登录
  7. Altium Designer18中DDR3的数据和地址线如何分别布等长线,走蛇形线
  8. 肖秀荣:2022考研政治大纲解读及复习建议
  9. Beta函数和Gamma函数的关系
  10. TensorFlow.js简介