问一个递归执行顺序的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a Javascript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
Javascript 权威指南第 5 版
Closure: The Definitive Guide
waiaan
V2EX    Javascript

问一个递归执行顺序的问题

  •  
  •   waiaan 2017-10-18 09:12:15 +08:00 3955 次点击
    这是一个创建于 2966 天前的主题,其中的信息可能已经有所发展或是发生改变。
    function fn1(){
    fn1(); //(1)
    fn2(); //(2)
    }
    大致这么一个顺序,请问是必须等(1)的递归执行完之后才会执行(2)吗?
    谢谢。
    28 条回复    2017-10-19 14:12:10 +08:00
    123s
        1
    123s  
       2017-10-18 09:15:10 +08:00
    fn2 不会执行吧
    brickyang
        2
    brickyang  
       2017-10-18 09:18:14 +08:00 via iPhone
    你这个递归没有退出条件,会无限死循环
    waiaan
        3
    waiaan  
    OP
       2017-10-18 09:18:39 +08:00
    @brickyang
    @123s
    只是举个例子
    BBCCBB
        4
    BBCCBB  
       2017-10-18 09:18:56 +08:00
    是的,
    但是你这个代码写的有问题, 没有出口, 导致了死循环.
    yulitian888
        5
    yulitian888  
       2017-10-18 09:20:30 +08:00
    @123s 只要不是死循环,fn2 应该被执行。
    但是楼主问的“执行完之后”的“后”怎么算呢,每一个循环体里都要被执行一次 fn2,对外层的 fn1 调用可以算“后”,但是同级来开,fn2 就是 fn1 的一部分
    waiaan
        6
    waiaan  
    OP
       2017-10-18 09:20:30 +08:00
    @BBCCBB
    我知道,只是举个例子说明一下我的问题。
    关注点在执行顺序上。
    Damon4V
        7
    Damon4V  
       2017-10-18 09:25:56 +08:00
    顺序 fn1.....fn1 -> fn2....fn2
    polun
        8
    polun  
       2017-10-18 09:28:08 +08:00   1
    不知道楼主是不是这个意思:

    var times = 1;

    function fun1() {
    console.log(times + ' fun1...');
    if (times++ < 9) {
    fun1();
    }

    fun2();
    console.log('--- 我是分割线 ---');
    }

    function fun2() {
    console.log(times + ' fun2...');
    }

    fun1();

    自己可以试试
    secondwtq
        9
    secondwtq  
       2017-10-18 09:29:52 +08:00 via iPhone
    可以去看看二叉树的遍历
    zheng5200
        10
    zheng5200  
       2017-10-18 09:31:48 +08:00 via iPhone
    是的,前一个执行完了,才会执行下一个
    waiaan
        11
    waiaan  
    OP
       2017-10-18 09:41:49 +08:00
    @secondwtq
    就是从这来的,这一段没看懂。
    waiaan
        12
    waiaan  
    OP
       2017-10-18 09:47:03 +08:00
    @polun 多谢。
    zhaoweichen
        13
    zhaoweichen  
       2017-10-18 09:48:28 +08:00   1
    假设 fn1 有正常的判断条件
    fn1_level0 => fn1_level1 => ... => fn1_leveln => fn2_leveln => fn2_leveln-1 => ... fn2_level0

    lz 需要补一补函数调用和 stack 的维护
    waiaan
        14
    waiaan  
    OP
       2017-10-18 11:47:04 +08:00
    @zhaoweichen 谢谢
    JKeita
        15
    JKeita  
       2017-10-18 15:10:54 +08:00
    每个递归层次,fn2 都会在 fn1 执行完后执行
    waiaan
        16
    waiaan  
    OP
       2017-10-18 17:42:37 +08:00
    @JKeita 然而并不是
    JKeita
        17
    JKeita  
       2017-10-19 09:03:59 +08:00
    你自己写个函数试下就清楚了,同级下 fn2 绝对是在 fn1 执行完后执行。
    JKeita
        18
    JKeita  
       2017-10-19 09:12:24 +08:00
    @waiaan
    function fn1($i)
    {
    if($i == 0){
    return;
    }
    fn1(--$i);
    echo "fn1:$i done. \n";
    fn2();
    }

    function fn2()
    {
    echo "exec fn2 \n";
    }

    fn1(3);

    输出结果:
    fn1:0 done.
    exec fn2
    fn1:1 done.
    exec fn2
    fn1:2 done.
    exec fn2
    waiaan
        19
    waiaan  
    OP
       2017-10-19 09:47:18 +08:00
    @JKeita 谢谢,请教一下为什么和 8 楼的执行顺序不一样?
    JKeita
        20
    JKeita  
       2017-10-19 09:48:38 +08:00
    @waiaan 8 楼那个写的就是错的,他用循环调用 fn1,而且输出也是在递归之前就执行了
    JKeita
        21
    JKeita  
       2017-10-19 09:51:07 +08:00
    @waiaan 看出他不是循环调用,他是在递归调用 fn1 之前就执行 console.log 进行输出,所以不一样
    waiaan
        22
    waiaan  
    OP
       2017-10-19 10:56:26 +08:00
    @JKeita


    var inOrderTraverseNode = function (node, callback) {
    if (node !== null) {
    inOrderTraverseNode(node.left, callback); //( 1 )
    callback(node.key);
    inOrderTraverseNode(node.right, callback);
    }
    };

    那这一段二叉树遍历的代码能否解释一下?为什么会等( 1 )递归结束了才开始执行后面的语句?实在没看懂,谢谢。
    JKeita
        23
    JKeita  
       2017-10-19 11:11:10 +08:00
    @waiaan 这里需要画二叉树会看得比较清楚,每次进入父节点函数时先递归左分支,左分子递归结束返回后紧接着执行父节点的 callback 回调方法,最后递归右分支。你这个是二叉树的中序遍历,具体你网上查查图片会看得比较清楚
    JKeita
        24
    JKeita  
       2017-10-19 11:17:16 +08:00
    @waiaan 为什么会等( 1 )递归结束了才开始执行后面的语句? 这里也是指 同级下执行顺序为 左,父,右
    waiaan
        25
    waiaan  
    OP
       2017-10-19 12:01:53 +08:00
    @JKeita
    18 楼和 22 楼的代码差别在哪?一个每次进入 fn1 都会执行后面的“ echo "fn1:$i done. \n";”,一个要等到 inOrderTraverseNode 递归结束才会执行后面的“ callback(node.key);”
    多谢。
    vankid
        26
    vankid  
       2017-10-19 13:16:24 +08:00
    单线的,f1 退出后开始一个个反向执行 f2
    JKeita
        27
    JKeita  
       2017-10-19 14:02:30 +08:00
    @waiaan 你还是没理解啊,并没有差别,同级下左分支 inOrderTraverseNode 执行完后必定会 callback(node.key);,你要把递归是从最深层次开始每层执行完后再返回上层继续执行,同一层次 必定 会 先后 执行 inOrderTraverseNode(left);callback;inOrderTraverseNode(right);
    JKeita
        28
    JKeita  
       2017-10-19 14:12:10 +08:00
    @waiaan
    https://gss0.bdstatic.com/94o3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike92%2C5%2C5%2C92%2C30/sign=cda010f5f9deb48fef64a98c9176514c/79f0f736afc379313a0f0cbde1c4b74543a9113a.jpg
    如图,为二叉树中序遍历,callback 函数即为输出节点名称,输出为:D J G B H E A F I C.
    每个节点即为递归层次,输出顺序为:当前节点的左节点名称,当前节点名称,当前节点的右节点名称。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     903 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 20:49 PVG 04:49 LAX 12:49 JFK 15:49
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86