递归算法

递归和快速排序

感情迁移 提交于 2020-01-22 05:48:59
文章目录 递归 问题描述 基线条件和递归条件 栈 调用栈 递归调用栈 小结 快速排序 示例1 问题描述 欧几里得算法 使用D&C解决问题的两个步骤: 示例2 快速排序 工作原理 代码 小结 递归 问题描述 假设你在祖母的阁楼中翻箱倒柜,发现了一个上锁的神秘手提箱。祖母告诉你,钥匙很可能在下面这个盒子里,这个盒子里有盒子,而盒子里的盒子又有盒子。钥匙就在某个盒子中。为找到钥匙,你将使用什么算法? 方法一: 创建一个要查找的盒子堆。 从盒子堆取出一个盒子,在里面找。 如果找到的是盒子,就将其加入盒子堆中,以便以后再查找。 如果找到钥匙,则大功告成! 回到第二步。 方法二: 检查盒子中的每样东西。 如果是盒子,就回到第一步。 如果是钥匙,就大功告成! 第一种方法使用的是while循环:只要盒子堆不空,就从中取一个盒子,并在其中仔细查找。 def look_for_key ( main_box ) : pile = main_box . make_a_pile_to_look_through ( ) while pile is not empty : box = pile . grab_a_box ( ) for item in box : if item . is_a_box ( ) : pile . append ( item ) elif item . is_a_key ( ) :

左神算法书籍《程序员代码面试指南》——1_03如何使用递归函数和栈操作逆序一个栈

吃可爱长大的小学妹 提交于 2020-01-22 01:05:31
【题目】 一个栈依次压入1、2、3、4、5,那么从栈顶到栈底分别为5、4、3、2、1。 将这个栈转置后,从栈顶到栈底为1、2、3、4、5,也就是实现栈中元素的逆序, 但是只能用递归函数来实现,不能用其他数据结构。 【题解】 使用两个递归函数: 一个递归函数是将栈底的元素返回并删除 另一个函数是将返回的元素进行存入 【代码】 1 #pragma once 2 #include <iostream> 3 #include <vector> 4 #include <stack> 5 6 using namespace std; 7 8 //【题目】 9 //一个栈依次压入1、2、3、4、5,那么从栈顶到栈底分别为5、4、3、2、1。 10 //将这个栈转置后,从栈顶到栈底为1、2、3、4、5,也就是实现栈中元素的逆序, 11 //但是只能用递归函数来实现,不能用其他数据结构。 12 // 13 //【题解】 14 //使用两个递归函数: 15 //一个递归函数是将栈底的元素返回并删除 16 //另一个函数是将返回的元素进行存入 17 18 int getBottomData(stack<int>&s) 19 { 20 int res = s.top(); 21 s.pop(); 22 if (s.empty()) 23 return res;//将栈底元素弹出 24 else 25 {

用递归函数和栈操作逆序栈

妖精的绣舞 提交于 2020-01-22 01:04:35
用递归函数和栈操作逆序栈 题目描述 一个栈依次压入1,2,3,4,5那么从栈顶到栈底分别为5,4,3,2,1。将这个栈转置后,从栈顶到栈底为1,2,3,4,5,也就是实现了栈中元素的逆序,请设计一个算法实现逆序栈的操作,但是只能用递归函数来实现,而不能用另外的数据结构。 给定一个栈 Stack 以及栈的大小 top ,请返回逆序后的栈。 测试样例: [1,2,3,4,5],5 返回:[5,4,3,2,1] 链接: https://www.nowcoder.com/questionTerminal/ba7d7f5d1edf4d1690d66e12e951f6ea 来源:牛客网 注意不能使用额外的数据结构! 其实类似深度优先搜索。 C++代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 int level = 0; vector< int > reverseStackRecursively(vector< int > stack, int top) { if (top > 0){ int val = stack[top - 1]; ++level; stack = reverseStackRecursively(stack, top - 1); --level; stack[level] = val; } return stack; } 来源: https:/

栈与队列问题(主要是栈的使用)

人盡茶涼 提交于 2020-01-22 01:02:33
转载请注明原文地址: http://www.cnblogs.com/ygj0930/p/6857537.html 一:问题概述 栈与队列的相关算法题,一般都是基于对栈、队列基本性质的熟练掌握的前提下,如何巧妙地组合、包装,以达到某种原来数据类型所没有的性质。比如:设计出一种能getMin()获取栈中最小值的栈、利用栈实现队列等等。问题的本意为考察栈、队列的基本性质与基本操作的灵活使用,所以 解题思路也是从这边出发:怎么利用现有的数据结构以及其基本性质、操作,去组合、包装,实现题目要求? 二:栈、队的基本性质与操作 栈:后进先出。Java中Stack类实现了栈,基本操作有:empty()判断是否为空、peek()查看栈顶、pop()弹出栈顶、push()入栈。 队列:先进先出。Java中用LinkedList实现了队列(LinkedList也实现了List接口和deque接口,所以LinkedList中包含了list、单向队列、双向队列的操作),单向队列的基本操作有:peek()查看队首、poll()弹出队首、offer()加入队尾、size()返回大小。 三:设计一个可查询最值的栈 我们知道,基本的栈是“后进先出”的,栈中的最值没有固定的位置,所以想要靠位置记录来查找是行不通的;其次,栈中元素随着push/pop操作,最值是会变化的,怎么随着push/pop操作动态修改最值呢?

递归算法:爬楼梯问题

前提是你 提交于 2020-01-21 22:19:31
问题描述: 某人需要爬楼梯,他可以每次走1级或2级楼梯,输入楼梯的级数,求不同的走法数 例如:楼梯一共有3级,他可以每次都走1级;或者第一次走1级,第二次走2级;也可以第一次走2级,第二次走1级。一共有3种爬楼梯的方法。 输入: 输入包含若干行,每行包含一个正整数N,代表楼梯的级数,1<=N<=30 输出: 不同的走法数,每一行输入对应一行的输出 样例输入: 5 8 10 样例输出: 8 34 89 问题的分析及解决: 这题是一道递归的算法题。题目的核心难点只有一个,如何用递归思想去解决看似是排列组合的问题。 假设有N级台阶,有一个函数int Stairs(int N),可以输出N级台阶的走法。关于这N级台阶的爬楼梯方法,如果第一步走1级,那么剩下的N-1级台阶有Stairs(N-1)种走法;如果第一步走2级,那么剩下的N-2级台阶有Stairs(N-2)种走法。 即有:Stairs(N)=Stairs(N-1)+Stairs(N-2) 有么有很熟悉,斐波那契数列啊~当N=1时,有Stairs(1)=1;N=2,Stairs(2)=2 显然,这2个条件可以作为递归的终止条件,那么这个算法的代码也就轻易可以写出了 代码: #include <iostream> using namespace std; int stairs(int N); void main() { int N;

穷举法和递归算法

倾然丶 夕夏残阳落幕 提交于 2020-01-21 10:03:55
枚举算法(穷举法): 特点:将问题的所有可能的答案一一列举,然后根据条件判断此答案是否合适,合适就保留,不合适就丢弃。例如:找出1到100之间的素数,需要将1到100之间的所有整数进行判断。 枚举算法因为要列举问题的所有可能的答案,所有它具备以下几个特点: 1、得到的结果肯定是正确的; 2、可能做了很多的无用功,浪费了宝贵的时间,效率低下。 3、通常会涉及到求极值(如最大,最小,最重等)。 4、数据量大的话,可能会造成时间崩溃。 优缺点 优点:算法简单,在局部地方使用枚举法,效果十分的好 缺点:运算量过大,当问题的规模变大的时候,循环的阶数越大,执行速度越慢 递归算法: 特点:无限调用自身这个函数,每次调用总会改动一个关键变量,直到这个关键变量达到边界的时候,不再调用。 递归的三要素: 1、明确递归终止条件; 2、给出递归终止时的处理办法; 3、提取重复的逻辑,缩小问题规模。 来源: CSDN 作者: 王同學 链接: https://blog.csdn.net/qq_43605753/article/details/104058317

二叉树遍历,递归,栈,Morris

只愿长相守 提交于 2020-01-21 08:09:44
一篇质量非常高的关于二叉树遍历的帖子,转帖自http://noalgo.info/832.html 二叉树遍历(递归、非递归、Morris遍历) 2015年01月06日 | 分类: 数据结构 | 标签: 二叉树遍历 | 评论: 8条评论 | 浏览:6,603次 二叉树遍历是二叉树中最基本的问题,其实现的方法非常多,有简单粗暴但容易爆栈的递归算法,还有稍微高级的使用栈模拟递归的非递归算法,另外还有不用栈而且只需要常数空间和线性时间的神奇Morris遍历算法,本文将对这些算法进行讲解和实现。 递归算法 二叉树节点使用以下数据结构进行表示,包括关键字、左儿子、右儿子属性和一个带默认参数的构造函数。 struct成员的默认属性为public,于是可以直接访问。 struct Node { int val; Node *left, *right; Node(int v = 0, Node *l = NULL, Node *r = NULL) : val(v), left(l), right(r) {} }; 二叉树的递归算法非常简单,设置好递归出口之后,根据遍历的顺序,对当前节点的左右子递归调用自身即可。其前序、中序、后序遍历的代码如下。 void preorder1(Node *root) //递归前序遍历 { if (root == NULL) return; printf("%d ",

依赖注入、递归组件的用法

假如想象 提交于 2020-01-20 20:27:07
处理边界情况 $root 用来访问根组件 $parent 用来从一个子组件访问父组件的实例 ref 和 $refs 的用法 在组件上面使用 ref 这个属性绑定,属性值自取,然后就可以通过 $refs.属性名 这种方式去获取到指定组件的实例了。 其实不仅仅是组件能够使用 ref ,标签元素也能使用。 依赖注入 现在我们有一个需求,如果我们存在多个组件嵌套的,然后现在其中某一个组件想访问其曾祖父组件的方法,那么使用上面两种方式都是不可取的,这个时候官方提供了 provide 和 inject 这两个属性来解决这个问题。 provide 允许我们指定想要提供给后代组件的数据/方法,且该属性是一个方法,返回一个对象,键名就是我们要传到后代组件的标志 然后在任何后代组件里,我们都可以使用 inject 选项来接收指定的我们想要添加在这个实例上的属性。该属性是一个数组类型,跟 props 的数组语法类似 说到这里,有的人可能会觉得这不就是跟 props 差不多嘛。没错,它确实差不多,但是还是有区别的,比如,祖先元素不需要知道哪些后代组件使用它提供的属性;其次,后代组件也不需要知道被注入的属性来自哪里 代码如下: 父组件: <div id="app"> <child-com></child-com> </div> <template id="childCom"> <div> <span

算法简介

风格不统一 提交于 2020-01-20 06:37:33
基础算法简介 前提 递归 斐波那契数列 算法分类 回溯法 迷宫问题 动态规划 动态规划解决的问题 01简单背包问题 动态规划版 简单0-1背包 前提 我今天给大家讲一讲基础的算法,因为这块东西比较复杂,再加上本人其实也是一个小菜鸡,所以不敢涉及太多的理论知识,今天主要内容还是通过练习的方式让你们了解部分算法的大概思想。 递归 讲算法之前了,我们先来回顾一下递归的知识,以下是维基百科定义的递归 大部分的递归定义都由三个部分构成:基本情况的定义,递归法则和递归结束的情况,如果定义的对象是无限的,那么可以省略第三个部分。比如说,可以用递归定义的方式来定义如下的一个自然数集上的函数 f(0)=1 n>0,f(n)=n f(n-1). 举一个简单的例子,你和你的女朋友一起去看电影,你女朋友想知道你们坐的是第几排,但是电影院太黑了,没办法一排一排的数,那你就可以问你前面一个人,一排一排往前问(递归法则),直到前面没有人为止(终止条件)则递归的表达式为: f(1) = 1 n>1,f(n) = f(n-1)+1; 递归代码如下: //n>=1 if(n==1) return 1; return f(n-1)+1; 斐波那契数列 下面给大家出一道比较经典题,大家先思考一下: 大家应该都有了解过斐波那契数列把,它的定义如下: F(0) = 0; F(1) = 1; F(n) = F(n-1)+F(n

算法---递归

亡梦爱人 提交于 2020-01-20 02:06:05
1、什么是递归? “要理解递归,就得先了解什么是递归”,实际上这句话就是一个递归。哈哈,是不是把大家说蒙了,没关系,接下来举个从小就听 过的例子:从前有座山,山里有座庙,庙里有个和尚,和尚在讲故事,从前有座山,山里有座庙,庙里有个和尚,和尚在讲故事,从前有座山… 2、举例数组求和----计算数组某个区间内所有谁的和 package recursion ; public class Sum { public static int sum ( int [ ] arr ) { return sum ( arr , 0 ) ; } private static int sum ( int [ ] arr , int index ) { if ( index == arr . length ) { return 0 ; } return arr [ index ] + sum ( arr , index + 1 ) ; } public static void main ( String [ ] args ) { int [ ] nums = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 } ; System . out . println ( sum ( nums ) ) ; } } 3、链表具有天然的递归性 对于一个链表来说,我们可以理解成一个一个节点的挂接