二叉树T的叶节点中的值列表

时间:2015-03-31 10:13:01

标签: prolog binary-tree dcg

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] 

是否可能。

3 个答案:

答案 0 :(得分:4)

让我们使用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的条件构造会更好,更有效。我想把这个留给有兴趣的人。

答案 1 :(得分:4)

首先,我们将 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).

答案 2 :(得分:0)

与第一次实施相比,同样的解决方案可以表示为:

region

可以删除最后一行(lea(nil, []). lea(t(X, nil, nil), [X]). lea(t(_, A, B), L) :- lea(A, L1), lea(B, L2), append(L1, L2, L) L \= []. )(如果您接受查找每个解决方案的可能性)。