Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在prolog中返回二进制树的所有级别_Prolog - Fatal编程技术网

在prolog中返回二进制树的所有级别

在prolog中返回二进制树的所有级别,prolog,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))

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

> Prlog非常棘手,但这里有一个解决方案,它提供了一个真正的树遍历:

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\u value\u pairs/3
,生成
depth value
形式的解(例如
0-t
表示铺层深度
0
处的根节点
t
,或者
1-4
表示铺层深度
1
处的节点
4
,等等)。然后,它使用
keylistmerge/2
将列表中的所有深度值对合并为深度组,例如,
[0-[t]、1-[4,t]、…]
。然后,
maplist(keyvalue…
调用从列表中取消
Depth-
部分,最后的谓词调用
member/2
选择要绑定到输出
级别的每个列表

以下是其他谓词定义:

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.

请注意,我们依靠内置的
keysort/2
来保持顺序(稳定),从而保持二叉树中节点的L-R顺序。

这里有一个解决方案,它在构建每个级别的项目列表后遍历树

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