Prolog,二叉树

时间:2012-10-12 05:22:04

标签: prolog

我想找到二叉树最深的元素,到目前为止,代码仅适用于空树或高度为1。

这是代码 我的身高功能正常工作。

deepest(node(L,X,R),X):- height(L,0),height(R,0).
deepest(node(L,_,R),X):- height(L,D1),height(R,D2), D1 > D2,  deepest(L,X).
deepest(node(L,_,R),X):- height(L,D1),height(R,D2), D1 =< D2, deepest(R,X).

编辑:示例

?- deepest(node(node(node(leaf,8,leaf),20,leaf),
                      30,
                      node(node(leaf,88,leaf),33,node(leaf,888,leaf))),
                 X).
X = 8 ;
X = 88 ;
X = 888 ;
false.

2 个答案:

答案 0 :(得分:1)

我怀疑关系height(顺便说一下,在Prolog中有函数),对于任务来说是无用的,因为它会忘记所需的基本信息。

deepest(T, E) :-
    deepest(T, E, _).

deepest(node(L, X, R), E, D) :-
    deepest(L, EL, DL),
    deepest(R, ER, DR),
    (   DL > DR
    ->  E = EL, D is DL + 1
    ;   (   DL < DR
        ->  E = ER, D is DR + 1
        ;   (   DL > 0  % DL & DR are equals
            ->  E = L, D is DL % deepest is arbitrary here
            ;   E = X, D is 1
            )
        )
    ).
deepest(N, N, 0).
对于预期的数据结构

编辑,而不是deepest(N, N, 0).我认为使用它更清晰

deepest(_, _, 0).

答案 1 :(得分:0)

这是一个替代版本,它使用了一些基本的内置插件,即append/3keysort/2reverse/2maplist/3

deepest(Tree, N) :-
    deepest(Tree, 0, NL),
    maplist(strip_key, NL, N).

deepest(leaf, _, []). 
deepest(node(L, X, R), D, [DN-N|Res]) :-
    NewD is D + 1,
    deepest(L, NewD, LL), 
    deepest(R, NewD, RL),
    append([D-X|LL], RL, NL),
    keysort(NL, KL),
    reverse(KL, [DN-N|Rem]),
    first_key_run(Rem, DN, Res).

first_key_run([DN-N|Rem], DN, [DN-N|NL]) :-
    !, 
    first_key_run(Rem, DN, NL).
first_key_run(_, _, []).

strip_key(_K-V, V).

此版本在树中的每个节点上构建一个Depth-Node项列表,对列表执行keysort/2,这些列表最先排序(O(N·log(N)),反转顺序(O(N)),然后保持第一次相同最深的节点(O(N))。

此版本还计算完全同等深度的节点数。例如:

?- deepest(node(node(node(leaf,8,leaf),20,leaf),30,node(node(leaf,88,leaf),33,node(leaf,888,leaf))), X).
X = [88, 888, 8].