我正试图让一个程序以列表的方式返回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]
问题是我不知道如何让程序获得新的根。 有任何想法吗?另外,提前谢谢!
答案 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