在 Prolog 中,我们可以使用:
- 原子
nil代表一棵空二叉树,并且
-
t(Left, Root, Right) 形式的术语表示一个非空二叉树,其中Root 是树根的值,Left 和Right 是还有表示二叉树的术语。
为了使二叉树更易于查看,您可以使用以下谓词:
show(T) :-
show(T, 0).
show(nil, _).
show(t(Left, Root, Right), Indent) :-
Indent1 is Indent + 3,
show(Right, Indent1),
format('~*c~w\n', [Indent, 32, Root]),
show(Left, Indent1).
例子:
?- show( t(t(nil,1,nil), 2, t(nil,3,nil)) ).
3
2
1
true.
设List 是一个列表,表示任意二叉树的in-order 遍历,如下图所示:
那么,由于不同的二叉树可以有相同的中序遍历,那么对应于这样一个列表的二叉树可以描述如下:
% convert from in-order traversal list to binary tree
list_to_bt(List, Tree) :-
( List = []
-> Tree = nil
; Tree = t(Left, Root, Right),
append(Prefix, [Root|Suffix], List),
list_to_bt(Prefix, Left),
list_to_bt(Suffix, Right) ).
例子:
?- list_to_bt([1,2,3], T), show(T).
3
2
1
T = t(nil, 1, t(nil, 2, t(nil, 3, nil))) ;
3
2
1
T = t(nil, 1, t(t(nil, 2, nil), 3, nil)) ;
3
2
1
T = t(t(nil, 1, nil), 2, t(nil, 3, nil))
...
false.
如果您只想获得平衡二叉树(例如,对于每个节点,左右子树大小的绝对差最大为 1),那么您可以包括这个约束如下:
% convert from in-order traversal list to balanced binary tree (bbt)
list_to_bbt(List, Tree) :-
( List = []
-> Tree = nil
; Tree = t(Left, Root, Right),
append(Prefix, [Root|Suffix], List),
length(Prefix, Size1),
length(Suffix, Size2),
abs(Size1 - Size2) =< 1,
list_to_bbt(Prefix, Left),
list_to_bbt(Suffix, Right) ).
例子:
?- list_to_bbt([1,2,3], T), show(T).
3
2
1
T = t(t(nil, 1, nil), 2, t(nil, 3, nil)) ;
false.
如果您只想要任意列表中的平衡二叉搜索树,则必须在创建平衡二叉树之前对该列表进行排序:
% convert from arbitrary list to balanced binary search tree (bbst)
list_to_bbst(List, Tree) :-
sort(List, Sorted),
list_to_bbt(Sorted, Tree).
例子:
?- list_to_bbst([3,1,7,5,4,2,6], T), show(T).
7
6
5
4
3
2
1
T = t(t(t(nil, 1, nil), 2, t(nil, 3, nil)), 4, t(t(nil, 5, nil), 6, t(nil, 7, nil))) ;
false.
?- list_to_bbst([3,1,4,2], T), show(T).
4
3
2
1
T = t(t(nil, 1, nil), 2, t(nil, 3, t(nil, 4, nil))) ;
4
3
2
1
T = t(t(nil, 1, nil), 2, t(t(nil, 3, nil), 4, nil)) ;
4
3
2
1
T = t(t(nil, 1, t(nil, 2, nil)), 3, t(nil, 4, nil)) ;
4
3
2
1
T = t(t(t(nil, 1, nil), 2, nil), 3, t(nil, 4, nil)) ;
false.