返回prolog中所有级别的二叉树

时间:2011-03-31 02:24:52

标签: prolog

我正试图让一个程序以列表的方式返回BT的级别,我坚持这个:

nivel(nodo(L,Root,R)) :- nivel(nodo(L,Root,R),X),writeln(X).
nivel(vacio,[]).
nivel(nodo(L,Root,R),[Root|T]) :- nivel(L,T),nivel(R,T),writeln(T).

我正在尝试的输入输出示例是:

nivel(nodo(nodo(vacio,4,vacio), t, nodo(vacio,r,vacio))
  X =[t]
  X =[4,r]

问题是我不知道如何让程序获得新的根。 有任何想法吗?另外,提前谢谢!

2 个答案:

答案 0 :(得分:1)

Prolog相当棘手,但这里有一个考虑的解决方案,它提供了一个真正的level-order (L-R breadth-first)树遍历:

nivel(nodo(L,Root,R), Level) :-
    depth_value_pairs(nodo(L,Root,R), 0, DVPairs),
    keylistmerge(DVPairs, Groups),
    maplist(keyvalue, Groups, _, Values),
    member(Level, Values).

nivel/2是您的输入谓词。基本上,它使用depth_value_pairs/3生成Depth-Value形式的解决方案(例如,0-t来表示层深t处的根节点0,或{ {1}}表示ply深度1-4处的节点4等。然后,它使用1将列表中的所有深度值对合并到深度组中,例如keylistmerge/2。然后,[0-[t], 1-[4,t], ...]调用会破坏列表中的maplist(keyvalue...部分,最终谓词调用Depth-会选择每个列表绑定到输出member/2

以下是其他谓词定义:

Level

行使这一点给了我们:

depth_value_pairs(vacio, _, []).
depth_value_pairs(nodo(L, Root, R), Depth, [Depth-Root|Level]) :-
    NextLevel is Depth + 1,
    depth_value_pairs(L, NextLevel, LL),
    depth_value_pairs(R, NextLevel, RL),
    append(LL, RL, Level).

keyvalue(K-V, K, V).

keylistmerge(KVL, MKVL) :-
    keysort(KVL, [K-V|KVs]),
    keylistmerge([K-V|KVs], K, [], MKVL).
keylistmerge([], K, Acc, [K-Acc]).
keylistmerge([K0-V|KVs], K, Acc, MKVL) :-
    K == K0, !,
    append(Acc, [V], NewAcc),
    keylistmerge(KVs, K, NewAcc, MKVL).
keylistmerge([K0-V|KVs], K, Acc, [K-Acc|MKVs]) :-
    keylistmerge(KVs, K0, [V], MKVs).

请注意,我们依赖内置的?- nivel(nodo(nodo(vacio,4,nodo(vacio,5,vacio)), t, nodo(vacio,r,vacio)), Level). Level = [t] ; Level = [4, r] ; Level = [5] ; false. 来保持顺序(稳定),以便保留二叉树中节点的L-R顺序。

答案 1 :(得分:1)

这是一个解决方案,它会在构建每个级别的项目列表时遍历树。

nivel(Arbol, SubNivel):-
  nivel(Arbol, [], [], Items),
  member(SubNivel, Items),
  SubNivel \= [].

nivel(vacio, Items, SubNiveles, [Items|SubNiveles]).
nivel(nodo(Izq, Item, Der), Items, [], [[Item|Items]|NSubNiveles]):-
  nivel(Izq, [], [], [MSubItems|MSubNiveles]),
  nivel(Der, MSubItems, MSubNiveles, NSubNiveles).
nivel(nodo(Izq, Item, Der), Items, [SubItems|SubNiveles], [[Item|Items]|NSubNiveles]):-
  nivel(Izq, SubItems, SubNiveles, [MSubItems|MSubNiveles]),
  nivel(Der, MSubItems, MSubNiveles, NSubNiveles).

nivel / 4的第二个子句是一个hack,因为算法事先并不知道树的高度。

测试用例:

?- nivel(nodo(nodo(nodo(nodo(vacio,f,vacio),e,nodo(vacio,g,vacio)),b,vacio),a,nodo(vacio,c,nodo(vacio,d,vacio))), X).
X = [a] ;     --> Root
X = [c, b] ;  --> First Level
X = [d, e] ;  --> Second Level
X = [g, f] ;  --> Third Level