Data structures prolog中基于遍历的二叉搜索树查找

Data structures prolog中基于遍历的二叉搜索树查找,data-structures,prolog,binary-tree,binary-search-tree,Data Structures,Prolog,Binary Tree,Binary Search Tree,我试图编写一个Prolog谓词,为给定的遍历提供一个可能的二进制搜索树。我选择像t(根,左子树,右子树)那样表示树,叶子只是t(数字),当子树不存在时,它的值是nil 这是我到目前为止所做的(仅适用于本例中的后序遍历): 这在一个方面运行良好,但在另一个方向挂起: ?- post(t(8, t(5, t(2), nil), t(12, t(9), t(16))), Trav). Trav = [2, 5, 9, 16, 12, 8]. ?- post(Tree, [2, 5, 9, 16, 1

我试图编写一个Prolog谓词,为给定的遍历提供一个可能的二进制搜索树。我选择像
t(根,左子树,右子树)
那样表示树,叶子只是
t(数字)
,当子树不存在时,它的值是
nil

这是我到目前为止所做的(仅适用于本例中的后序遍历):

这在一个方面运行良好,但在另一个方向挂起:

?- post(t(8, t(5, t(2), nil), t(12, t(9), t(16))), Trav).
Trav = [2, 5, 9, 16, 12, 8].

?- post(Tree, [2, 5, 9, 16, 12, 8]).
Tree = t(8, nil, t(12, nil, t(16, nil, t(9, nil, t(5, nil, t(2)))))) ;
Tree = t(8, nil, t(12, nil, t(16, nil, t(9, nil, t(5, nil, t(2, nil, nil)))))) ;
[execution hangs here]

我意识到
post
不需要二元搜索树,即不要求左子树中的所有节点都小于根节点,右子树中的所有节点都大于根节点,因此我还写了以下内容:

tree(t(_)).
tree(nil).
tree(t(N, L, R)) :-
    tree(L), tree(R),
    ( L = t(NL, _, _) -> NL < N ; true ),
    ( R = t(NR, _, _) -> NR > N ; true ).
tree(t(u))。
树(无)。
树(t(N,L,R)):-
树(L),树(R),
(L=t(NL,,)->NLNR>N;真)。
我想我可以做
?-post(Tree,[…]),Tree(Tree)。
让Prolog只返回实际的二进制搜索树。然而,我似乎已经被困在生成可能的树上了


如何改进代码?这是否可行?

我的建议是为不同的方向编写不同的代码。下面是将列表转换回树的代码。与原始代码的主要区别在于,我们在重建树之前先解构列表(使用
last/3
append/3
)。注意,我在第三个子句(两个
maplist/2
调用)中添加了检查搜索树的代码,但是如果您想单独保留它们,也可以删除它们

postlist_to_tree([],nil).
postlist_to_tree([X],t(X)).
postlist_to_tree(Xs,t(Last,LT,RT)):-
    last(Fore,Last,Xs),
    append(LL,RL,Fore),
    maplist('>='(Last),LL),
    maplist('=<'(Last),RL),
    postlist_to_tree(LL, LT),
    postlist_to_tree(RL, RT).

您的数据结构是非正统的。通常您有
nil
t(Value,Left,Right)
,然后一个叶节点是
t(Value,nil,nil)
。因此您正在遍历一个二叉搜索树,但列表没有排序,因为您是按顺序而不是按顺序进行的。是这样吗?你到底在做什么?教科书中的这一章为你提供了一些答案和代码:
postlist_to_tree([],nil).
postlist_to_tree([X],t(X)).
postlist_to_tree(Xs,t(Last,LT,RT)):-
    last(Fore,Last,Xs),
    append(LL,RL,Fore),
    maplist('>='(Last),LL),
    maplist('=<'(Last),RL),
    postlist_to_tree(LL, LT),
    postlist_to_tree(RL, RT).
post2(Tree,List):-
    ground(List),
    !,
    postlist_to_tree(List,Tree).
post2(Tree,List):-
    post(Tree,List).