【问题标题】:list of the values in the leaf nodes of binary tree T二叉树 T 的叶节点中的值列表
【发布时间】:2015-06-04 15:24:47
【问题描述】:

List 是二叉树的叶节点中的值列表,我试图弄清楚如何输出它。这给了我所有的节点,但我只需要叶子。

lea(nil,[]).
lea(t(X,L,R),[X|L]) :-
   lea(L,L1), 
   lea(R,L2), 
   append(L1,L2,L).

运行它给了我:

?- lea(t(a,t(b,t(d,nil,nil),t(e,nil,nil)),t(c,nil,t(f,t(g,nil,nil),nil))),
       List). 
List = [a, b, d, e, c, f, g]

但我需要

List = [d, e,g] 

有没有可能。

【问题讨论】:

    标签: prolog binary-tree dcg


    【解决方案1】:

    让我们使用 DCG - 定从句语法。我们从您的原始定义开始:

    lea(T, L) :-
       phrase(values(T), L).
    
    values(nil) -->
       [].
    values(t(X,L,R)) -->
       [X],
       values(L),
       values(R).
    

    现在,我们需要将自己限制在那些属于叶子的t/3。一种可能性是列举所有情况:

    lea2(T, L) :-
       phrase(leaves(T), L).
    
    leaves(nil) -->
       [].
    leaves(t(X,nil,nil)) -->
       [X].
    leaves(t(_,L,R)) -->
       { dif(L+R,nil+nil) },
       leaves(L),
       leaves(R).
    

    使用类似于if_/3 的条件构造会更好、更有效。我想把这个留给感兴趣的人。

    【讨论】:

      【解决方案2】:

      首先,我们扩展 if_/3 以使用 DCG:

      if_(C_1, Then_0, Else_0) -->                    % if_//3
         { call(C_1, Truth) },
         { functor(Truth, _, 0) },                    % safety check
         (  { Truth == true  } -> phrase(Then_0)
         ;  { Truth == false },   phrase(Else_0)
         ).
      

      使用if_//3 (=)/3 ,我们可以用一个子句(而不是两个子句)处理非零树节点:

      lea3(T, Ls) :-
         phrase(leaves(T), Ls).
      
      leaves(nil) --> [].
      leaves(t(X,L,R)) -->
         if_(L-R = nil-nil, [X], []),
         leaves(L),
         leaves(R).
      

      【讨论】:

      • 不确定,但我认为(至少)在 SWI-Prolog 中您可以直接使用 (->)/2 构造
      • 没有。 (->)/2 立即提交,可能会删除部分解决方案集。
      • 不应该把call(Then_0)读成phrase(Then_0)吗?那么您将不再需要add//1empty//0。而且(=)/3equal_truth/3 更紧凑。尔格if_(L-R = nil-nil, [X], []).
      【解决方案3】:

      同样的解决方案,距离第一次实现不远,可以表示为:

      lea(nil, []).
      lea(t(X, nil, nil), [X]).
      lea(t(_, A, B), L) :-
          lea(A, L1),
          lea(B, L2),
          append(L1, L2, L)
          L \= [].
      

      可以删除最后一行 (L \= [])(如果您接受找到所有解决方案的可能性)。

      【讨论】:

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