递归算法

DFS深度优先算法学习

佐手、 提交于 2019-12-04 14:25:58
刚开始学习算法,参考大佬博客还是有很多不明白的,于是一步步解析,写下笔记记录。 大佬博客地址: https://blog.csdn.net/fuzekun/article/details/85220468 问题描述   n个人参加某项特殊考试。   为了公平,要求任何两个认识的人不能分在同一个考场。   求是少需要分几个考场才能满足条件。 输入格式   第一行,一个整数n(1<n<100),表示参加考试的人数。   第二行,一个整数m,表示接下来有m行数据   以下m行每行的格式为:两个整数a,b,用空格分开 (1<=a,b<=n) 表示第a个人与第b个人认识。 输出格式   一行一个整数,表示最少分几个考场。 样例输入 5 8 1 2 1 3 1 4 2 3 2 4 2 5 3 4 4 5 样例输出 4 样例输入 5 10 1 2 1 3 1 4 1 5 2 3 2 4 2 5 3 4 3 5 4 5 样例输出 5 因为数据量很小可以使用回溯算法。 应用两层回溯: 第一层回溯是将考生放在不同考场里面产生的效果,比如学生3号可以放在教室1和教室2中那么放在那一个教室会产生更好的效果这是一层回溯。 第二层回溯是考生放入以前的考场还是考生自己重新用一个考场。比如考生3号可以放进教室1和教室2,也可以放进教室3。 应用简单的剪枝技巧:

深入理解递归算法之斐波那契数列(兔子数列)

你。 提交于 2019-12-04 11:54:04
问题描述: 斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列以如下被以递推的方法定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*) 找到递归的递推公式后,使用代码是实现就比较好理解了 import java.util.*; public class Rabbit { public static void main(String[] args){ System.out.println("请输入一个整数来表示你希望计算的月份:"); Scanner scan= new Scanner(System.in); int i=scan.nextInt(); int s=calc(i); System.out.printf("%d个月份后兔子的数量为:%d",i,s); } public static int calc(int n){ if(n==1||n==2){ return 1; } else{ return calc(n-1)+calc(n-2); } } } 二:使用递归的思想实现计算一个数字的阶乘 import

23 遍历二叉树的非递归算法

烈酒焚心 提交于 2019-12-04 09:33:57
例子:中序遍历非递归算法 实现代码: //中序遍历的非递归算法 int InOrderTraverse_No_DiGui(BiTree T){ BiTree p; //顶底指向二叉树中节点的游标 InitStack(S); //初始化栈 p = T; //p指向所给的二叉树根节点 while(p || !StackEmpty(S)){ if(p){ //若当前节点非空 Push(S, p); //将当前节点入栈 p = p->lchild; //游标指向当前节点的左孩子 }else{ Pop(S, q); //出栈,将栈顶节点返回到一个二叉树节点类型的变量 q 中 printf("%c", q->data); //输出该节点的数据域 p = q->rchild; //游标指向当前节点的右孩子 } }//while return 1; //遍历结束 } View Code 来源: https://www.cnblogs.com/CPU-Easy/p/11854078.html

python中的函数递归和迭代问题

倖福魔咒の 提交于 2019-12-04 09:26:54
一、递归 1、递归的介绍 什么是递归?    程序调用自身的编程技巧称为递归( recursion)。递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法, 它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量 。递归的能力在于用有限的语句来定义对象的无限集合。一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。   递归要注意的是,它是直接或间接调用自身,所以在使用递归时,必须有一个明确的递归结束条件,称为递归出口,否则,他就会陷入死循环。 尾递归   具体可以看一下博客 https://blog.csdn.net/ialexanderi/article/details/81482878   如果一个函数中所有递归形式的调用都出现在函数的末尾,我们称这个递归函数是尾递归的。当递归调用是整个函数体中最后执行的语句且它的返回值不属于表达式的一部分时,这个递归调用就是尾递归。尾递归函数的特点是在回归过程中不用做任何操作,这个特性很重要,因为大多数现代的编译器会利用这种特点自动生成优化的代码。 python不是一门函数式编程语言,本身不支持尾递归(没有对尾递归做优化)

树和二叉树一篇就搞定!

[亡魂溺海] 提交于 2019-12-04 03:42:46
二叉树铺垫——树 前面几篇文章我们主要介绍的线性表,栈,队列,串,等等,都是一对一的 线性结构 ,而今天我们所讲解的 “树” 则是一种典型的 非线性结构 ,非线性结构的特点就是,任意一个结点的直接前驱,如果存在,则一定是唯一的,直接后继如果存在,则可以有多个,也可以理解为一对多的关系,下面我们就先来认识一下树 树的概念 下图我们日常生活中所见到的树,可以看到,从主树干出发,向上衍生出很多枝干,而每一根枝干,又衍生出一些枝丫,就这样组成了我们在地面上可以看到的树的结构,但对于每一个小枝丫来讲,归根结底,还是来自于主树干的层层衍生形成的。 我们往往需要在计算机中解决这样一些实际问题 例如: 用于保存和处理树状的数据,例如家谱,组织机构图 进行查找,以及一些大规模的数据索引方面 高效的对数据排序 先不提一些复杂的功能,就例如对于一些有树状层级结构的数据进行建模,解决实际问题,我们就可以利用 “树” 这种结构来进行表示,为了更符合我们的习惯,我们一般把 “树” 倒过来看,我们就可以将其归纳为下面这样的结构,这也就是我们数据结构中的 “ 树” 树中的常见术语 结点 :包含数据项以及指向其他结点的分支,例如上图中圆 A 中,既包含数据项 A 又指向 B 和 C 两个分支 特别的,因为 A 没有前驱,且有且只有一个,所以称其为根结点 子树 :由根结点以及根结点的所有后代导出的子图称为树的子树

【算法分析】递归算法的几个经典例子

♀尐吖头ヾ 提交于 2019-12-04 02:33:02
例一:整数划分问题     将正整数n表示成一系列正整数之和:n=n1+n2+…+nk,其中n1≥n2≥…≥nk≥1,k≥1。正整数n的这种表示称为正整数n的划分。求正整数n的不同划分个数。 例如:正整数6有如下11种不同的划分: 6; 5+1; 4+2,4+1+1; 3+3,3+2+1,3+1+1+1; 2+2+2,2+2+1+1,2+1+1+1+1; 1+1+1+1+1+1 在本例中,如果设p(n)为正整数n的划分数,则难以找到递归关系,因此考虑增加一个自变量:将最大加数n1不大于m的划分个数记作q(n,m)。 下面对可能出现的四种情况进行分析: ① m=1:   当m等于1时,对n的划分只可能1+1+1+……+1这一种情况。 ②m>n时:   当m大于n时,由于划分中不可能出现负数,所以{n1, n2, n2,… , nk}(n = n1+n2+n3+……+nk)只可能出现小于等于n的整数。故有q(n, m)=q(n, n) ⑤m=n时:   当m等于n时,包含n自身的划分和没有n的划分两个部分。而包含n自身的划分只有一种情况,故有有q(n, n)=1+q(n,n-1) ④m<n时:   n的m划分有包含m和不包含m两个部分。其中包含m的部分用集合可表示为{m, {x1, x2, x3, 4,…, xk}}(其中x1+x2+……+xk=n-m)【详解见图1】

Python使用递归绘制谢尔宾斯基三角形

非 Y 不嫁゛ 提交于 2019-12-04 02:14:57
谢尔宾斯基三角形使用了三路递归算法,从一个大三角形开始,通过连接每一个边的中点,将大三角型分为四个三角形,然后忽略中间的三角形,依次对其余三个三角形执行上述操作。 运行效果: 源代码: 1 import turtle 2 3 4 def draw_triangle(points, color, my_angle): 5 my_angle.fillcolor(color) 6 my_angle.up() 7 my_angle.goto(points[0][0], points[0][1]) 8 my_angle.down() 9 my_angle.begin_fill() 10 my_angle.goto(points[1][0], points[1][1]) 11 my_angle.goto(points[2][0], points[2][1]) 12 my_angle.goto(points[0][0], points[0][1]) 13 my_angle.end_fill() 14 15 16 def get_mid(p1, p2): 17 return ((p1[0]+p2[0])/2, (p1[1]+p2[1])/2) 18 19 20 def sierpinski(points, degree, my_angle): 21 colormap = ['blue', 'red

数据结构与算法之美学习笔记:第十讲

≡放荡痞女 提交于 2019-12-04 02:13:45
一、开篇问题 推荐注册返佣金的这个功能我想你应该不陌生吧?现在很多App都有这个功能。这个功能中,用户A推荐用户B来注册,用户B又推荐了用户C来注册。我们可以说,用户C的“最终推荐人”为用户A, 用户B的“最终推荐人”也为用户A,而用户A没有“最终推荐人”。 一般来说,我们会通过数据库来记录这种推荐关系。在数据库表中,我们可以记录两⾏数据,其中actor_id表示用户id,referrer_id表示推荐人id。 基于这个背景,我的问题是, 给定一个用户ID,如何查找这个用户的“最终推荐人”? 带着这个问题,我们来学习今天的内 容,递归(Recursion) 二、如何理解递归 1、电影院案例 周末你带着女朋友去电影院看电影,女朋友问你,咱们现在坐在第几排啊?电影院里面太黑了,看不清,没法数,现在你怎么办? 2、用递归解决你在第几排的问题 别忘了你是程序员,这个可难不倒你,递归就开始排上用场了: 于是你就问前面一排的人他是第几排,你想只要在他的数字上加一,就知道自己在哪一排了。 但是,前面的人也看不清啊,所以他也问他前面的人。就这样一排一排往前问,直到问到第一排的人,说我在第一排, 然后再这样一排一排再把数字传回来。直到你前面的人告诉你他在哪几排,于是你就知道答案了。 这就是一个非常标准的递归求解问题的分解过程: 去的过程叫“递”,回来的过程叫“归” 。基本上

巧用递归解决矩阵最大序列和问题

本秂侑毒 提交于 2019-12-03 15:40:46
之前同事问了一道需要点脑洞的算法题,我觉得蛮有意思的,思路可能会给大家带来一些启发,特意在此记录一下 题目 现有一个元素仅为 0,1 的 n 阶矩阵,求连续相邻(水平或垂直,不能有环)元素值为 1 的序列和的最大值 假设有如下矩阵 则此矩阵连续相邻元素为 1 的序列和分别为 4, 3,(如图示),可知这个矩阵序列和的最大值为 4 解题思路 要算序列和的最大值,我们可以先找出所有可能的序列和,然后取其中的最大值,那怎么找这些序列呢? 首先我们发现,每个序列的起点和终点必然是 1,我们可以遍历矩阵的每一个元素,如果元素值为 1,则将其作为序列的起点开始查找所有以这个元素为起点的序列,我们知道序列是可以向垂直和水平方向延伸的,所以我们可以以这个元素为起点,查找它的上下左右值为 1 的元素,再以找到的这些元素为起点,继续在元素的上下左右查找值为1的元素(递归),如果找不到符合条件的值,则序列终止,在遍历过程中保存每条序列遍历的元素,即可知晓每条序列的元素和,从而求得序列和的最大值 文字说得有点绕,接下来我们就以查找以下矩阵的最大序列和为例来详细看一下如何查找最大序列和 从左到右,从上到下遍历所有值为 1 的元素,第一个符合条件的元素在右上角,所以以这个元素为起点来查找序列 以这个元素为起点,查找这个元素上下左右为值为 1 的元素,发现只有这个元素下面的元素符合条件

【算法】递归

耗尽温柔 提交于 2019-12-03 12:04:44
递归是一个比较难理解的问题,但是递归是一种非常广泛的算法,如数据结构中的树和图都会应用队规的算法。一般大家会拿汉诺塔进行举例,但是还有更容易理解的例子。 周末你去看电影,然后你忘记了现在坐的是第几排了,电影院太黑了,看不清,没法数,怎么办? 这个时候就可以问递归解决了,于是你问前面的人是第几排,你想只要在他的数字上加一,就知道自己是第几排了。但是,前面的人也看不清是第几排呀,于是他也问他前面的人。就这样一排一排往前问,直到问道第一排的人,说我在第一排,这样一排一排再把数字传回来。 这是一个很标准的递归求解问题的分解过程。所有递归问题都可以用递归公式来表示。 总结一下,就是一个递归要满足三个条件: 1.一个问题的解可以分解成几个子问题的解 2.这个问题与分解之后的子问题,除了数据规模不同,求解思路完全一样 3.存在递归终止条件 即写出一个递归函数,例子如下: f(n) = f( n-1) +1 其中,f(1) = 1 改成代码为: #python 3 def f(x:int) ->int: if ( n==1): return 1 return f( n-1) +1 再举个例子,假如这里有 n 个台阶,每次可以跨一个或者俩个台阶,请问走这 n 个台阶有多少种走法? 我们仔细想一下,实际上,我们可以根据第一步的走法把所有走法分为两类,第一类是第一步走了1个台阶