【发布时间】:2020-05-01 03:20:18
【问题描述】:
给定一个元素列表,返回所有可能包含该列表元素的平衡二叉树。在我们的例子中,一个有效的树结构是:tree(_, left, right)。例如:
?- avl_tree_planter(X, [yin, yang]).
X = tree(yang, tree(yin, nil, nil), nil) ;
X = tree(yin, tree(yang, nil, nil), nil) ;
X = tree(yin, nil, tree(yang, nil, nil)) ;
X = tree(yang, nil, tree(yin, nil, nil)) ;
我尝试使用中序、前序和后序遍历输出所有可能的选项:
abs_diff(L,R,D) :- D is L-R, L >= R.
abs_diff(L,R,D) :- D is R-L, R >= L.
height(nil,0).
height(tree(_,L,R), H) :-
height(L,HL), height(R,HR),
max_num(HL,HR,MaxH), H is MaxH + 1.
avl_tree_planter(nil,[]).
avl_tree_planter(tree(X,L,R), Xs) :-
height(L,HL), height(R,HR),
abs_diff(HL,HR,Diff), Diff =< 1,
avl_tree_planter(L,Ls), avl_tree_planter(R,Rs),
append(Ls,[X|Rs],Xs). % inorder
avl_tree_planter(tree(X,L,R), Xs) :-
height(L,HL), height(R,HR),
abs_diff(HL,HR,Diff), Diff =< 1,
avl_tree_planter(L,Ls), avl_tree_planter(R,Rs),
append(Rs, [X], Xs1), % postorder
append(Ls, Xs1, Xs).
avl_tree_planter(tree(X,L,R), Xs) :-
height(L,HL), height(R,HR),
abs_diff(HL,HR,Diff), Diff =< 1,
avl_tree_planter(L,Ls), avl_tree_planter(R,Rs),
append([X|Ls], Rs, Xs). % preorder
在一些在线解释器中输入:
avl_tree_planter(X,[a,b]).
它输出:
X = tree(a, nil, tree(b, nil, nil))
12 次然后进入无限循环,再一次无限循环。
我已经为递归设置了停止条件,那么我做错了什么?
【问题讨论】:
-
其中一个问题是您的
height/2谓词是一个generate-and-test 谓词:它首先生成 一棵树,然后检查它的高度。这意味着最终谓词将继续提出所有失败的高度树,但因此陷入无限循环。
标签: recursion tree prolog binary-tree avl-tree