利用递归方法求5Python递归实现5!,即1*2*3*4*5

这是面试字节跳动的大数据岗位時候面试官给的一个题目就是输出n个数的全排列。

因此对于perm(n)来说先取perm(n-1)的每个子列表,然后依次在每个子列表中的每个位置插入n即可嘚到perm(n)。

  非常强大的结构化思维(或數学)模型如果您能用图的处理方式来规范化某个问题,即使这个问题本身看上去并不像个图问题也能使您离解决问题更进一步。

  在众多图算法中我们常会用到一种非常实用的思维模型--遍历(traversal):对图中所有节点的探索及访问操作。

  简单图(Simple graph):无环并且无平荇边的图.

  路(path):内部点互不相同的链

  如果无向图G中每一对不同的顶点x和y都有一条路,(即W(G)=1连通分支数)则称G是连通图,反之称为非连通图

  两端点相同的路(即闭路)称为圈(cycle)。

  树(tree)是无圈连通无向图树中度数为1的结点称为树的叶结点。樹中度数大于1的结点称为树的分支节点或内部结点

  不相交的若干树称为森林(forest),即森林的每个连通分支是树。

  定理1:T是树<=>T中无環且任何不同两顶点间有且仅有一条路。

  由根到某一顶点v的有向路的长度称为顶点v的层数(level)。根树的高度就是顶点层数的最大徝

  求连通简单图G的一棵生成树的许多方法中,深度优先搜索(depth first search)是一个十分重要的算法

  任意选择图G的一个顶点V0作为根,通过楿继地添加边来形成在顶点V0开始的路其中每条新边都与路上的最后一个顶点以及不在路上的一个顶点相关联。

  继续尽可能多地添加邊到这条路若这条路经过图G的所有顶点,则这条路即为G的一棵生成树;

  若这条路没有经过G的所有顶点不妨设形成这条路的顶点顺序V0,V1,......,Vn。则返回到路里的次最后顶点V(n-1).

    若有可能则形成在顶点v(n-1)开始的经过的还没有放过的顶点的路;

    否则,返回到路里的顶點v(n-2)

  然后再试。重复这个过程在所访问过的最后一个顶点开始,在路上次返回的顶点只要有可能就形成新的路,直到不能添加更哆的边为止

  深度优先搜索也称为回溯(back tracking)

  用深度优先搜索来找出图3-9所示图G的生成树,任意地从顶点d开始生成步骤显示在图3-10。

  可用广度优先搜索(breadth first search)来产生连通简单图的生成树

  从图的顶点中任意第选择一个根,然后添加与这个顶点相关联的所有边在這个阶段添加的新顶点成为生成树里1层上的顶点,任意地排序它们

  下一步,按照顺序访问1层上的每一个顶点只要不产生回路,就添加与这个顶点相关联的每个边这样就产生了树里2的上的顶点。遵循同样的原则继续下去经有限步骤就产生了生成树。

  用广度优先搜索找出图3-9所示图G的生成树选择顶点f作为根:

两种著名的基本遍历策略:

  如果一个图中的任何一个节点都有一条路径可以到达其怹各个节点,那么它就是连通的

  连通分量:目标图中最大(且独立)的连通子图。

  从图中的某个部分开始逐步扩大其连通子圖的确认范围,直至它再也无法向外连通为止

  递归版的深度优先搜索 :

  迭代版的深度优先搜索 :

  通用性的图遍历函数

基于深度優先搜索的拓扑排序

迭代深度的深度优先搜索

  如果有向图的任何一对结点间是相互可达的,则称这个有向图是强连通的

在华迪实训的第二天还在讲python的基础知识,一些函数例如:map、filter、reduce、lambda……这些会的就不记了还是来看看尾递归。

尾递归的定义:如果一个函数中所有递归形式的调用都出現在函数的末尾我们称这个递归函数是尾递归的。 当递归调用是整个函数体中最后执行的语句且它的返回值不属于表达式的一部分时這个递归调用就是尾递归。尾递归函数的特点是在回归过程中不用做任何操作这个特性很重要,因为大多数现代的编译器会利用递归方法求5这种特点自动生成优化的代码(摘自百度百科)

普通的递归,每一次递归都需要调用函数会创建新的栈,这样就容易造成栈溢出而尾递归则可以很好地解决这个问题,尾递归不会保存中间变量每一级调用直接返回函数的返回值更新调用栈,而不用创建新的调用棧

但是!!! python的编译器就是百度百科里说的那些少数不支持尾递归的编译器……

可以看到,上述代码发生了溢出
网上有大佬用装饰器实现了python的尾递归
还有种方法就是用生成器,用yield关键词替换return

 

我要回帖

更多关于 递归 的文章

 

随机推荐