首页 > 代码库 > 递归转换为迭代的一种通用方式
递归转换为迭代的一种通用方式
把递归算法转化为非递归算法, 有如下两种基本方法:
1)通过分析, 用迭代的方式自底向上. 有时需用栈保存参数
2)模拟函数调用过程, 用栈保存入参
尾递归:
一个函数只在return处调用自身。很多编译器就能将其转换为迭代
T tailRecursive(U x, V y) { if (bar(x, y)) { return exit(x,y); } else { ... // block 1 return tailRecursiveFoo(w, z); } } To: T Iterative(U x, V y) { while (!bar(x, y)) { // 调用递归子函数的条件if -> while ... // block 1 x = w; // 传入递归子函数的参数 y = z; } return exit(x,y); // 递归出口 }
更通用点的伪代码:
T recursiveFoo(U param1, V param2){ U local1; V local2; ... // code block 1 recursiveFoo (local1, local2); ... // code block 2 recursiveFoo (param1, local2); ... // code block 3 recursiveFoo (local1, param2); ... // code block 4 } To: T iterativeFoo (U param1, V param2) { U local1; V local2; Stack stk; stk.push(javaBean:{param1, param2, local1, local2, 1}); // 进入函数, 第一次调用: 创建栈并将局部变量压栈 while (!stk.empty()) { // 循环直至栈空 + 弹栈 FooStackInfo stkTop = stk.pop(); param1 = stkTop.param1; param2 = stkTop.param2; local1 = stkTop.local1; local2 = stkTop.local2; switch (stkTop.location) { // 递归块->switch-case包裹 case 1: ... // code block 1 //向前匹配块 stk.push(javaBean:{param1, param2, local1, local2, 2}); //第二次调用 stk.push(javaBean:{local1, local2, local1, local2, 1}); //传参 break; case 2: ... // code block 2 //向前匹配块 stk.push(javaBean:{param1, param2, local1, local2, 3}); //第三次调用 stk.push(javaBean:{param1, local2, local1, local2, 1}); //传参 break; case 3: ... // code block 3 //向前匹配块 stk.push(javaBean:{param1, param2, local1, local2, 4}); //第四次调用 stk.push(javaBean:{local1, param2, local1, local2, 1}); //传参 break; case 4: ... // code block 4 //程序末尾(无匹配) break; } } }
注: 如果递归子函数都在一起且在递归母函数程序的末尾,则无需记录调用位置且无需使用switch case,只需要push。
递归转换为迭代的一种通用方式
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。