递归算法

Continuation Passing Style

孤者浪人 提交于 2020-02-07 12:08:24
CPS(Continuation Passing Style, 后续传递风格), 是指将程序的控制流显示地用 Continuation 来传递,而不是像 direct style 那样明确指出下一条语句的编码风格。符合 CPS 的函数需要一个额外的参数:一个显式的Continuation (通常为一个只有一个参数的函数)。一个CPS函数通过以返回值为参数,调用Continuation的方式来返回函数值。当我们调 用一个CPS函数式,被调用的函数需要一个额外的 return procedure 来供被调用的函数使用。用CPS的方式来表达代码可 以使普通程序中很多不明确的内容变得明确。例如,函数的返回值看起来就像是对Continuation的调用,参数的求值顺序也 变得明确,同时,尾调用(tail call)也被直接传递给调用者(caller)。 一个函数可以被自动地从 direct style 转换成 continuation passing style。当在命令式或者过程式语言的编译器中 需要表达SSA(事实上,SSA可以被视作CPS的一个子集)时,编译器可以使用CPS来表达中间代码。 正常函数的返回都隐含一个continuation,就是利用这个函数的返回值来 做的后续事情,而cps的本质就是将这个隐式的 continuation显式的当做参数传递进去

【Python数据结构与算法笔记day36】7.2. 二叉树的遍历+深度优先遍历+ 广度优先遍历(层次遍历)

吃可爱长大的小学妹 提交于 2020-02-07 10:36:43
文章目录 7.2. 二叉树的遍历 二叉树的遍历 深度优先遍历 广度优先遍历(层次遍历) 7.2. 二叉树的遍历 二叉树的遍历 树的遍历是树的一种重要的运算。所谓遍历是指对树中所有结点的信息的访问,即依次对树中每个结点访问一次且仅访问一次,我们把这种对所有节点的访问称为遍历(traversal)。那么树的两种重要的遍历模式是深度优先遍历和广度优先遍历, 深度优先一般用递归,广度优先一般用队列。一般情况下能用递归实现的算法大部分也能用堆栈来实现。 深度优先遍历 对于一颗二叉树,深度优先搜索(Depth First Search)是沿着树的深度遍历树的节点,尽可能深的搜索树的分支。 那么深度遍历有重要的三种方法。这三种方式常被用于访问树的节点,它们之间的不同在于访问每个节点的次序不同。这三种遍历分别叫做先序遍历(preorder),中序遍历(inorder)和后序遍历(postorder)。我们来给出它们的详细定义,然后举例看看它们的应用。 先序遍历 在先序遍历中,我们先访问根节点,然后递归使用先序遍历访问左子树,再递归使用先序遍历访问右子树 根节点->左子树->右子树 def preorder ( self , root ) : """递归实现先序遍历""" if root == None : return print root . elem self . preorder (

[数据结构与算法]第6章 递归

偶尔善良 提交于 2020-02-07 02:28:41
个人博客文章地址 文章目录 6.1 递归需要遵守的重要规则 6.2 递归-迷宫问题 6.3 递归-八皇后问题(回溯算法) 6.1 递归需要遵守的重要规则 执行一个方法时,就创建一个新的受保护的独立空间(栈空间) 方法的局部变量是独立的,不会相互影响, 比如n变量 如果方法中使用的是引用类型变量(比如数组),就会共享该引用类型的数据. 递归必须向退出递归的条件逼近,否则就是无限递归,出现StackOverflowError,死龟了:) 当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕。 6.2 递归-迷宫问题 说明: 小球得到的路径,和程序员设置的找路策略有关即:找路的上下左右的顺序相关 再得到小球路径时,可以先使用(下右上左),再改成(上右下左),看看路径是不是有变化 测试回溯现象 思考: 如何求出最短路径? 代码实现: public class MiGong { public static void main ( String [ ] args ) { // 先创建一个二维数组,模拟迷宫 // 地图 int [ ] [ ] map = new int [ 8 ] [ 7 ] ; // 使用1 表示墙 // 上下全部置为1 for ( int i = 0 ; i < 7 ; i ++ ) { map

匿存函数,内存函数,递归函数,二分法查找

∥☆過路亽.° 提交于 2020-02-05 21:01:22
一.匿名函数(lambda) 语法: lambda 参数: 返回值 函数名统一都叫lambda 1.把普通函数转换成匿名函数 def func(n) return n * n ret = func(9) print(ret) 普通 a = lambda n: n * n ret = a(9) print(ret) 匿名 其中a可以认为是函数名,但是在__name__中函数名统一是lambda print(func.__name__) #查看函数名 print(a.__name__) #__name__的值都是<lambda> 查看函数名 def func(a, b) return a + b x = lambda a, b : a+b print(x(a , b)) 两个参数的匿名函数 def func(x, y) return x, y s = lambda x, y :(x, y)#如果不放(),s会被分为两部分 lambda x, y :x和y print(s(250, 38)) 两个返回值的匿名函数 fn = lambda *args :max(args) #匿名函数一定是一行函数 print(fn(1,3,8,56))#56 求最大值 二.sorted() 排序函数 语法:sorted(iterable, key, reverse) key:排序规则. 运行流程:

Day 15 内置函数补充

血红的双手。 提交于 2020-02-05 20:19:22
内置函数 1, lambda 匿名函数 lambda 参数: 返回值 函数名统一都叫lambd # print("你好. 我\\叫周润发") # 对用户是友好的. 非正式的字符串 # # # 正式(官方)的字符串, 面向对象的时候 # print(repr("你好, 我\'叫周润发")) # 程序中内部存储的内容, 这个是给程序员看的 # print("我叫%r" % "周润发") # %r 实际上调用的是repr() # 原样输出 # print(r"马化腾说:\"哈哈哈, \" \n\t") print("你好") # 用户看着舒服 print(repr("你好")) # 真实的字符串表示形式(正式的) __str__() __repr__() # 普通的正常的函数 # def func(n): # return n * n # # # ret = func(9) # # print(ret) # # # # # 匿名函数, 语法: lambda 参数: 返回值 # a = lambda n : n * n # # ret = a(9) # # print(ret) # b = lambda x: x+1 # print(a(5)) # 函数的名字可以认为是a # # print(func.__name__) # 查看函数的名字 # print(a.__name__) # _

树据结构与算法——二分搜索树 动画演示

…衆ロ難τιáo~ 提交于 2020-02-05 19:05:18
文章目录 一、二分查找法 二分查找法变变种:floor和ceil 二、二分搜索树 实现查找表的比较: 二分搜索树定义 插入元素 查找元素 三、二分搜索树的遍历 二分搜索树的遍历(深度优先遍历) 二分搜索树的层序遍历(广度优先遍历) 四、二分搜索树删除节点 删除最大值,最小值 删除任意节点 附录   二叉搜索树是用来解决查找问题的,在介绍二叉搜索树之前,先学习二分查找法。 一、二分查找法   二分查找法只能对于 有序数列 使用(排序后的数组),在中间找一个元素v如果不是v,这在<v和>v两部分查找,时间复杂度为O(logn),如下图所示: 二分查找代码: // 二分查找法,在有序数组arr中,查找target // 如果找到target,返回相应的索引index // 如果没有找到target,返回-1 template < typename T > int binarySearch ( T arr [ ] , int n , T target ) { // 在arr[l...r]之中查找target int l = 0 , r = n - 1 ; while ( r > l ) { //int mid = (l + r)/2; // 防止极端情况下的整形溢出,使用下面的逻辑求出mid int mid = l + ( r - l ) / 2 ; //如果刚好找到 if ( arr [

非递归全排序(非字典算法)

假装没事ソ 提交于 2020-02-05 13:30:46
非c++ next_permutation方式 数组不可有重复值(等待改进中) 思路: nums = [1,2,3, 4] 先建立空lists 数量为n! = 4! = 24 [ [], [], [], . . . ] sPtr = 0 [1, 2, 3, 4] 3!=6次插入nums[sPtr]后,指针sPtr后移(超出回归0) [ 1 , // sPtr = 0 1 , 1 , 1 , 1 , 1 , 2 , // sPtr = 1 … … … ] [1, 2, 3, 4] 插入前检测nums[sPtr] 是否已存在当前list中,是则指针sPtr后移(超出回归0) 2!=2次插入nums[sPtr]后,指针sPtr后移(超出回归0) [ [ 1 , 2 // sPtr = 1 1 , 2 1 , 3 // sPtr = 2 1 , 3 1 , 4 // sPtr = 3 1 , 4 … // sPtr = 0 … … ] [1, 2, 3, 4] 插入前检测nums[sPtr] 是否已存在当前list中,是则指针sPtr后移(超出回归0) 1!=1次插入nums[sPtr]后,指针sPtr后移(超出回归0) [ 1 , 2 , 3 1 , 2 , 4 1 , 3 , 2 1 , 3 , 4 1 , 4 , 2 1 , 4 , 3 … … … ] [1, 2, 3, 4]

第3章 栈和队列

。_饼干妹妹 提交于 2020-02-05 09:01:48
3.1 栈的定义及抽象数据类型 栈(stack)是一种特殊的线性表,这种表只能在固定的一端进行插入与删除运算。通常称固定插入、删除的一端为栈顶(top),而另一端称为栈底(bottom)。位于栈顶和栈底的元素分别称为顶元和底元。当表中没有元素时,称为空栈。为了与一般的线性表相区别,通常将栈的插入操作称为入栈,将删除操作称为出栈。 线性表S=(a,b,c,d,e) 将S中的元素按照a、b、c、d、e的顺序依次入栈,则出栈的元素顺序为e、d、c、b、a 可以发现,最先进入栈中的元素a最后才出栈,最后入栈的元素e最先被出栈,因为栈的这一特性,故又将其称为后进先出的线性表(lastinfirstout,简称为LIFO)。 3.2 栈的实现 栈的实现既可以采用顺序存储结构也可以采用链式存储结构。采用顺序存储结构实现的栈称为顺序栈,采用链式存储结构实现的栈称为链栈 3.2.1 顺序栈 栈的初始化操作是指按指定的大小为栈动态分配一片连续的存储区,并将该存储区的首地址同时送给栈顶指针top和栈底指针base,表示栈里没有任何元素,此时的栈为空栈。若base的值为NULL时则表明栈不存在。当插入一个新元素时栈顶指针加1,当删除一个元素时栈顶指针减1。栈顶指针top始终比顶元超前一个位置,因此栈满的条件是top-base=stacksize。图3-3所示为栈顶指针和栈中元素的关系。 值得注意的是

递归实现角谷算法

给你一囗甜甜゛ 提交于 2020-02-05 01:17:06
#include using namespace std; int Kakutani_theorem(int n, int step) { if (n == 1) { cout << n; return step; } if (n % 2 == 0) { step++; cout << n<<" "; return Kakutani_theorem(n / 2, step); } else { step++; cout << n << " "; return Kakutani_theorem(n*3+1 , step); } } int main() { int n = 0; cin >> n; cin.clear(); cout << "所有进行过程为: "; int step=Kakutani_theorem(n,0); cout << endl; cout << "步数为: " << step; return 0; } 来源: CSDN 作者: ldbite 链接: https://blog.csdn.net/ldbite/article/details/104172293

面试中遇到递归算法

喜夏-厌秋 提交于 2020-02-05 00:15:29
前几天在博客园看到有人面试时,遇到递归算法题,一时手痒就解了一个。顺便网上又找来几个,也实现了。给大家分享一下,开阔一下思路,没准你明天面试就能用上。 1、编写一个方法用于验证指定的字符串是否为反转字符,返回true和false。请用递归算法实现。(反转字符串样式为"abcdedcba") 2、一列数的规则如下: 1、1、2、3、5、8、13、21、34...... 求第30个是多少 3、一列数的规则如下: 1、12、123、1234、12345、123456......,求第n个数的递归算法(n<=9)。 4、将一整数逆序,如987654321变为123456789。 5、一个射击运动员打靶,靶一共有10环,连开10枪打中90环的可能行有多少种? 以上的前提:不能用数组 或转成字符串处理,也不能用内置函数,如C#的幂函数(Math.Pow) 1 using System; 2 3 namespace RecursionAlgorithms 4 { 5 class Program 6 { 7 private static bool fn1(ref string str, ref int from, ref int to) 8 { 9 if (from >= to) return true; 10 if (str[from++] != str[to--]) return false;