【问题标题】:Prolog to count all the leaf nodes in a binary treeProlog计算二叉树中的所有叶节点
【发布时间】:2018-10-26 06:31:09
【问题描述】:

我需要使用 prolog 计算二叉树的所有内部节点我可以使用以下代码计算所有节点

internal(tree(_,L,R), I) :- internal(L, I2), internal(R, I3), I is I2 + I3 + 1.
internal(nil, 0).

我认为通过将基本情况更改为

internal(tree(_,nil, nil), 0).

我可以让它工作,但它返回 false。

这是一个应该返回 4 internal(tree(8,tree(5,tree(2,nil,nil),tree(7,nil,nil)), tree(9,nil,tree(15) 的测试用例,tree(11,nil,nil),nil))),I).

谁能告诉我我的错误在哪里? 谢谢

阅读您的建议后,我得到了这个,但它仍然失败。

internal(tree(_,L,R), I) :- internal(L, I2), internal(R, I3), I is I2 + I3. 
internal(tree(_,nil, R), I):- !, internal(R, I3), I is I3 + 1. 
internal(tree(_,L, nil), I):- !, internal(L, I3), I is I3 + 1.
internal(tree(_,nil, nil), 0).
internal(nil, 0).

【问题讨论】:

  • 提示:+1 在这里做什么?
  • 您的呼叫是否使用l 作为结果? l 不是一个变量,而是一个常量。所以你应该使用 大写 v 标识符。
  • @WillemVanOnsem 结果调用使用大写 i,而不是 l,据我了解,+1 是在找到基本案例的解决方案后向每个节点添加 1,这将返回 0
  • 但是在你的例子中你有一个tree(_, nil, tree(_, _, _))。如果您删除了internal(nil, 0),这与归纳或基本情况如何匹配?
  • 但如果你有一个tree(_, nil, tree(_, _, _)),那么左边的孩子是nil,右边的孩子是tree,所以基本情况足够,也不是归纳满足,因为它会在孩子中调用internal/2,因此它会调用internal(nil, I1)

标签: prolog binary-tree


【解决方案1】:

如果将谓词更改为:

internal(tree(_,nil, nil), 0).
internal(tree(_,L,R), I) :- internal(L, I2), internal(R, I3), I is I2 + I3 + 1.

那么对于具有nil 子节点和非nil 子节点的树,这将失败。

确实:如果树是tree(1, nil, tree(2, nil, nil)),那么Prolog 将首先尝试满足基本情况,但正弦nil 不等于tree(_, nil, nil),那就失败了。接下来它旨在满足递归情况,并首先统一L = nilR = tree(2, nil, nil)。现在它调用internal(L, I2),但由于不能满足internal(nil, I1),所以它失败了。

因此,我们可以首先构造一个谓词,满足两个子树是否产生一个内部节点:

isinternal(tree(_, _, _), _).
isinternal(_, tree(_, _, _)).

因此,如果至少有一个子树是tree(_, _, _).,则此谓词成功。现在我们可以使用这个谓词来计算内部节点的数量:

internal(nil, 0).
internal(tree(_, nil, nil), 0).
internal(tree(_, L, R), I) :-
    isinternal(L, R),
    internal(L, NL),
    internal(R, NR),
    I is NL + NR + 1.

上述内容在可读性方面可以改进。我把它留作练习。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-12
    • 1970-01-01
    • 1970-01-01
    • 2021-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多