tree - 如何在序言中实现树算法的尾递归

标签 tree prolog binary-tree tail-recursion

如何将以下内容转换为尾递归版本。

sum(void,0).
sum(t(V,L,R),S) :- 
  sum(L,S1),
  sum(R,S2),
  S is V + S1 + S2.

维护单个累加器似乎是不可能的,因为分支在 2^n 个量级。

一个可能的解决方案是让累加器在每次迭代时向列表添加一个新的累加器。 也许上述解决方案是最优的?

提前致谢。

最佳答案

是的,您的解决方案是最优的,因为它会为树中的每个节点恰好调用 sum/2 谓词一次(而且您不能少调用)。不,您可以通过自己使用累加器实现堆栈来使其尾递归。

这是一个示例(未测试)。展平谓词可以与 sum 结合,但这里为了清楚起见,它们是不同的(两者都是尾递归的):

flatten([],           Acc, Acc).
flatten([void|ToGo],  Acc, Result) :-
    flatten(ToGo, Acc, Result).
flatten([t(V,L,R)|ToGo], Acc, Result) :-
    flatten([L,R|ToGo], [t(V,L,R)|Acc], Result).

flatten(Root, Result) :-
    flatten([Root], [], Result).

sum([], Result, Result).
sum([t(V,_,_)|ToGo], Acc, Result) :-
    NewAcc is Acc+V,
    sum(ToGo, NewAcc, Result).

sum(Tree, Result) :-
    flatten(Tree, FlatTree),
    sum(FlatTree, 0, Result).

关于tree - 如何在序言中实现树算法的尾递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1521079/

相关文章:

binary-tree - 查找仅给定中序遍历的二叉树

java - 如何使用 Streams API 取消扁平化的层次结构

python - 二叉树获取每个级别的所有节点

Java 二进制表达式树 - 检查表达式中的括号

Prolog逻辑难题和约束规划

java - 此代码是否适用于二叉树中的欧拉之旅?

c++ - 二叉树形成错误

javascript - 一般树的二叉树

prolog - 图中的循环检测

prolog - 将术语转换为原子并在 YAP prolog 中保留变量名称