给出一个计算树深度的函数:

function treeDepth(curtree)
{
if(curtree == null)
return 0;
else
{
var leftDepth = treeDepth(curtree.left);
var rightDepth = treeDepth(curtree.right);
return 1 + Math.max(leftDepth, rightDepth);
}
}

现在要用CPS风格重写这个函数。

避免函数的返回值,而是将返回值传入continuation。记住,continuation就是这个函数完成后需要做的事情。于是写出如下代码

function treeDepth(curtree, afterDepth)
{
if(curtree == null)
afterDepth(0);
else
{
// undone: var leftDepth = treeDepth(curtree.left);
// undone: var rightDepth = treeDepth(curtree.right);
afterDepth(1 + Math.max(leftDepth, rightDepth));
}
}

这里假定加法和求最大值不写成CPS风格,以降低难度。

现在需要组合递归调用。考虑第二个递归调用,嗯,它的continuation是什么?也就是,当右子树的深度确定好了之后需要做哪些事情?两件事,第一,左右子树的深度的最大值需要被计算出来然后加1;第二,需要保证,做完后将会调用continuation。于是,写一个闭包来完成这两件事情。

function treeDepth(curtree, afterDepth)
{
if(curtree == null)
afterDepth(0);
else
{
function afterRight(rightDepth)
{
afterDepth(1+Math.max(leftDepth, rightDepth));
}
// undone: var leftDepth = treeDepth(curtree.left);
treeDepth(curtree.right, afterRight);
}
}

嗯,有进步了。那么,当左子树的深度确定后需要做什么?将左深度传给continuation,这个continuation在右树上面递归来决定右树深度,然后决定两者最大值,然后调用 afterDepth 这个continuation。

function treeDepth(curtree, afterDepth)
{
if(curtree == null)
afterDepth(0);
else
{
function afterLeft(leftDepth)
{
function afterRight(rightDepth)
{
afterDepth(1+Math.max(leftDepth, rightDepth));
}
treeDepth(curtree.right, afterRight);
}
treeDepth(curtree.left, afterLeft);
}
}

原文:https://blogs.msdn.microsoft.com/ericlippert/2005/08/11/recursion-part-five-more-on-cps/

递归——CPS(二)的更多相关文章

  1. Python学习笔记 之 递归、二维数组顺时针旋转90°、正则表达式

    递归.二维数组顺时针旋转90°.正则表达式 1.   递归算法是一种直接或间接调用自身算法的过程. 特点: 递归就是在过程或函数里调用自身 明确的递归结束条件,即递归出口 简洁,但是不提倡 递归次数多 ...

  2. 递归——CPS(一)

    程序中为什么需要栈stack? 普通的程序中,接触到子程序和函数的概念,很直观地,调用子程序时,会首先停止当前做的事情,转而执行被调用的子程序,等子程序执行完成后,再捡起之前挂起的程序,这有可能会使用 ...

  3. python基础(9)--递归、二叉算法、多维数组、正则表达式

    1.递归 在函数内部,可以调其他函数,如果一个函数在内部调用它本身,这个函数就是递归函数.递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于裂解 递归算法解决问题的特点: 1)递归是 ...

  4. python 基础篇 16 递归和二分数查找与编码补充回顾

    编码回顾补充: 回顾编码问题:        编码相当于密码本,关系到二进制与看懂的文字的的对应关系.    最早期的密码本:        ascii码:只包含英文字母,数字,特殊字符.       ...

  5. JS递归及二叉搜索树的移除节点

    1递归含义:在某时某刻某个条件下调用包含自己的函数 2:注意点:⑴递归过程中一定要加限制条件,要不然会陷入死循环: 死循环eg: function f(someP){ f(somP); } f(4); ...

  6. 递归——CPS(三)

    JScript不是天然支持CPS,但是可以写一个分发引擎使得能工作在CPS风格下.一般只有一个活动的continuation,所以可以定义规则:JScript CPS 函数允许有返回,但是它们做的最后 ...

  7. PHP递归获取二维数组中指定key的值

    $data = [ "resulterrorCode" => 0, "resultraw" => [ "result" => ...

  8. 数据结构&算法(二)_算法基础之前传(递归、时间复杂度、空间复杂度、二分查找)

    什么是算法: 间而言之算法(Algorithm):一个计算过程,解决问题的方法 递归的两个特点: 调用自身 结束条件 递归示例: def func(x): : print("我的小鲤鱼&qu ...

  9. 二叉搜索树的结构(30 分) PTA 模拟+字符串处理 二叉搜索树的节点插入和非递归遍历

    二叉搜索树的结构(30 分) PTA 模拟+字符串处理 二叉搜索树的节点插入和非递归遍历   二叉搜索树的结构(30 分) 二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则 ...

随机推荐

  1. Xilinx-Zynq Linux内核源码编译过程

    本文内容依据http://www.wiki.xilinx.com网址编写,编译所用操作系统为ubuntu 14 1.交叉编译环境的安装配置 1)http://www.wiki.xilinx.com/I ...

  2. 向输出到console的文字加样式

    Chrome 控制台新玩法-向输出到console的文字加样式   有兴趣的同学可以文章最后的代码复制贴到控制台玩玩. Go for Code 在正常模式下,一般只能向console 控制台输出简单的 ...

  3. Redis系统学习 三、使用数据结构

    前言:上一章,简单介绍了5种数据结构,并给出了一些用例.现在是时候来看看一些高级的,但依然很常见的主题和设计模式 一.大O表示法(Big O Notation ) 常用时间复杂度O(1)被认为是最快速 ...

  4. C#基础知识回顾--线程传参

    C#基础知识回顾--线程传参 在不传递参数情况下,一般大家都使用ThreadStart代理来连接执行函数,ThreadStart委托接收的函数不能有参数, 也不能有返回值.如果希望传递参数给执行函数, ...

  5. .net中获取图像缩略图的函数GetThumbnailImage

    关于.net中获取图像缩略图的函数GetThumbnailImage的一些认识. 在很多图像软件中,打开一幅图像的时候都会显示其缩略图,在看图软件中这样的需求更为常见.如何快速的获取缩略图的信息并提供 ...

  6. 基于BrokerPattern服务器框架

    基于BrokerPattern服务器框架 RedRabbit 经典网游服务器架构 该图省略了专门用途的dbserver.guildserver等用于专门功能的server,该架构的优点有: l Log ...

  7. Linux设备驱动开发详解-Note(5)---Linux 内核及内核编程(1)

    Linux 内核及内核编程(1) 成于坚持,败于止步 Linux 2.6 内核的特点 Linux 2.6 相对于 Linux 2.4 有相当大的改进,主要体现在如下几个方面. 1.新的调度器 2.6 ...

  8. 行业介绍:车载DVD MID 导航用料一般包含国腾LVDS芯片GM8284C/GM8283

    车载DVD MID 导航用料一般包含国腾LVDS芯片 GM8284C/GM8283/替代SN75LVDS83,THC63LVDM83C , 音频ES7144/CS4344,  龙讯MHL HDMI芯片 ...

  9. dtree实现上下级关系的显示

    在实际开发中我们常常要涉及到到在页面上显示上下级关系这样的需求 ,我的实现方法: 环境:S2SH+mysql 数据库结构如下图: 其中mgr字段是指经理,也就是自己的上一级 映射信息: Action和 ...

  10. ClickOnce部署疑难杂症:更新时部署与应用程序标识不一致问题。要安装此应用程序,请修改此文件的清单版本或卸载之前存在的应用程序。

    使用ClickOnce部署winform应用程序.无论是安装或者自动更新都极为方便,但有时候一些疑难杂症也令人头疼 1.注意每次部署完成之后 setup.exe无需覆盖,只需要在Application ...