码迷,mamicode.com
首页 > 其他好文 > 详细

递归——CPS(二)

时间:2016-07-01 21:31:09      阅读:318      评论:0      收藏:0      [点我收藏+]

标签:

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

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(二)

标签:

原文地址:http://www.cnblogs.com/sjjsxl/p/5634221.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!