二叉树可以用2个谓词来定义:
emptyBT
,空二叉树。
BTTree(N,T1,T2)
如果N
是具有左子树T1
和右子树T2
的二叉树的根,则为真,其中T1
中的所有项目{1}}小于或等于N
且T2
中的所有项都大于N
。
编写一个实现以下谓词的Prolog程序:
insert(I,T1,T2)
是由于我被插入二叉树T2
而产生的二叉树,则 T1
为真。
preorder(T,L)
是由二叉树L
的前序遍历生成的节点列表,则 T
为真。
inorder(T,L)
是由二叉树L
的顺序遍历生成的节点列表,则 T
为真。
postorder(T,L)
是由二叉树L
的后序遍历生成的节点列表,则 T
为真。
search(T,I)
中包含I
,则 T
为真。
height(T,H)
是二叉树H
的高度,则 T
为真。空树的高度为0
,而一个项目的树的高度为1
。
到目前为止,这是我的代码:我不知道它是否正确,是否有任何帮助或指针 非常感谢!
isempty(nil) :- !.
isempty(tree(nil,nil,nil)).
bTTree(tree(_,nil,nil)).
bTTree(tree(N,Left,nil)) :- Left@=<N.
bTTree(tree(N,nil,Right)) :- N@<Right.
bTTree(tree(_,Left,Right)) :- bTTree(Left), bTTree(Right).
bTTree(tree(N,Left,Right)) :- Left@=<N, N@<Right.
%traversals.
%preorder -- N,Left,Right
preorder(t,L) :- bTTree(t),
bTTree(t(N,Left,Right)),
append(N,[Left|Right],L).
preorder(t,L) :- bTTree(t(_,Left,_),
preorder(Left,L).
preorder(t,L) :- bTTree(t(_,_,Right),
preorder(Right,L).
%inorder -- Left,N,Right.
inorder(t,L) :- bTTree(t),
bTTree(t(N,Left,Right)),
append(Left,[N|Right],L).
inorder(t,L) :- bTTree(t(N,_,_)), inorder(N,L).
inorder(t,L) :- bTTree(t(_,_,Right)), inorder(Right,L).
%postorder -- Left,Right,N
postorder(t,L) :- bTTree(t),
bTTree(t(N,Left,Right)),
append(Left,[Right|N],L).
postorder(t,L) :- bTTree(t(_,_,Right)),
inorder(Right,L).
postorder(t,L) :- bTTree(t(N,_,_)),
append(_,[_|N],L).
search(t,I) :- bTTree(t(I,_,_)). %searches each node for I
search(t,I) :- bTTree(t(_,I,_)).
search(t,I) :- bTTree(t(_,_,I)).
search(t,I) :- bTTree(t(_,N,_)), search(N,I).%recursive method to search left branch for I
search(t,I) :- bTTree(t(_,_,N)), search(N,I).%recursive " " " right branch for I
height(t,H) :- bTTree(t(nil,nil,nil)), H is 0. %height of empty tree is 0
height(t,H) :- bTTree(t(_,nil,nil)), H is 1. %height of single node Btree is 1
height(t,H) :-
bTTree(t(_,Left,Right)), %otherwise height of bTree is the max
height(Left, H1), %height of left or right branch plus 1
height(Right, H2),
H is max(H1,H2) + 1.
insert(I,t1,t2) :-
bTTree(t1(X,L,_)),
bTTree(t2(X,L,I)).
insert(I,t1,t2) :-
bTTree(t1(nil,nil,nil)),
bTTree(t2(I,nil,nil)).
insert(I,t1,t2) :-
bTTree(t1(X,L,_)),
bTTree(t2(X,L,I)).
答案 0 :(得分:1)
为了清楚起见,我认为您的代码无法正常工作,并且没有显示任何有用的编码实践。然后我使用紧凑表示法实现,其中-
是空树,树是t(LeftSubtree, Int, RightSubtree)
。根据需要,LeftSubtree中的所有整数都小于Int等...
ins(I, -, t(-, I, -)).
ins(I, t(L, X, R), t(P, Y, Q)) :-
( I < X
-> ins(I, L, U),
(P, Y, Q) = (U, X, R)
; I > X
-> ins(I, R, U),
(P, Y, Q) = (L, X, U)
; (P, Y, Q) = (L, X, R) % already in, nothing to do
).
inl([N|Ns], T0, T) :-
ins(N, T0, T1),
inl(Ns, T1, T).
inl([], T, T).
inl / 3它是一个实用程序,它将所有的int插入树中并“返回”结果。 一些测试:
inl([3,6,1],-,X).
X = t(t(-, 1, -), 3, t(-, 6, -)) ;
false.
?- inl([3,6,1,1],-,X).
X = t(t(-, 1, -), 3, t(-, 6, -)) .
?- inl([3,6,1,1,4],-,X).
X = t(t(-, 1, -), 3, t(t(-, 4, -), 6, -)) ;
false.
答案 1 :(得分:0)
我想提供一个与@CapelliC 相同的答案,但有一个解释,可能还有一个友好的代码。
% it is true when X is greater than Y
gt(X,Y):- X > Y.
% create a node with only X
% createnode(+Tree, +Value, -t (-Value, -LeftLeaf, -RightLeaf))
createnode(nil, X ,t(X, nil ,nil)).
% base case
% avoid the duplicate
% otherwise, create a node
createnode(t(X, Left, Right), X, t(X, Left, Right)):-!. % the "!" cut down the backtracking, it's often more efficient
% create a node to a tree with the value X
% if X is smaller, create a node, with the value X, to Left1 subtree
% which backtracks to the base case
createnode(t(Root, Left, Right), X, t(Root, Left1, Right)):-
gt(Root, X),!,
createnode(Left, X, Left1).
createnode(t(Root, Left, Right), X, t(Root, Left, Right1)):-
gt(X, Root),!,
createnode(Right, X, Right1).
% base case
% the NewTree equals the Result tree
% and the list is empty, then the backtracking stops
insertnode([],Tree,Tree).
% insert a list of tree node
insertnode([X|Xs], Tree, Result):-
createnode(Tree, X, NewTree),
insertnode(Xs, NewTree, Result).
查询:
?-insertnode([7,6,12],nil,Tree).
Tree = t(7, t(6, nil, nil), t(12, nil, nil)).
?- createnode(nil,7,T1),createnode(T1,12,T2),createnode(T2,6,T3)
T1 = t(7, nil, nil),
T2 = t(7, nil, t(12, nil, nil)),
T3 = t(7, t(6, nil, nil), t(12, nil, nil)).