我应该求一棵二叉树的宽度,即同一层的最大节点数。
我应该定义:width_tree(Tree, Result)
。
我试过了,但我不明白如何计算同一级别的节点。 我想过考虑两个谓词,一个用于左侧,一个用于右侧,例如:
width_tree([Node, Left, Rigth], Result):-
width_tree(Left, 0, Result),
width_tree(Rigth, 0, Result).
但我不明白如何考虑有多少个节点。
我该怎么办?
这是树:
[12, [8, [5, [2, nil, nil], nil],[11, nil, nil]], [65, [42, nil, nil], [99, nil, nil]]]
结果是4,因为在第三层有4个节点(5, 11, 42, 99)
答案 0 :(得分:2)
您可以先定义一个谓词来更新宽度列表:
% update_widths(+Widths, +Level, -NewWidths)
update_widths([], L, [w(L,1)]).
update_widths([w(L0,W0)|R0], L, [w(L0,W1)|R0]) :- L0==L, !, W1 is W0 + 1.
update_widths([w(L0,W0)|R0], L, [w(L0,W0)|R1]) :- L0\=L, update_widths(R0, L, R1).
示例:
?- update_widths([],1,A), update_widths(A,2,B), update_widths(B,2,C), update_widths(C,2,D).
A = [w(1, 1)],
B = [w(1, 1), w(2, 1)],
C = [w(1, 1), w(2, 2)],
D = [w(1, 1), w(2, 3)].
之后,您可以定义一个谓词来获取给定二叉树的宽度列表:
% get_widths(+Tree, +Level, +Widths, -NewWidths)
get_widths(nil, _, Widths, Widths).
get_widths([_,Left,Right], Level, Widths, NewWidths) :-
NextLevel is Level + 1,
update_widths(Widths, Level, Widths0),
get_widths(Left, NextLevel, Widths0, Widths1),
get_widths(Right, NextLevel, Widths1, NewWidths).
% A tree
tree([12,[8,[5,[2,nil,nil],nil],[11,nil,nil]],[65,[42,nil,nil],[99,nil,nil]]]).
示例:
?- tree(T), get_widths(T, 1, [], W).T = [12, [8, [5, [2, nil, nil], nil], [11, nil, nil]], [65, [42, nil, nil], [99, nil, nil]]],
W = [w(1, 1), w(2, 2), w(3, 4), w(4, 1)].
然后,您可以定义一个谓词来查找宽度列表中的最大宽度:
% max_width(+Widths, -MaxWidth)
max_width([w(_,MaxWidth)], MaxWidth).
max_width([w(L1,W1),w(L2,W2)|Widths], MaxWidth) :-
( W1 > W2
-> max_width([w(L1,W1)|Widths], MaxWidth)
; max_width([w(L2,W2)|Widths], MaxWidth) ).
示例:
?- tree(T), get_widths(T,1,[],W), max_width(W,M).
T = [12, [8, [5, [2, nil, nil], nil], [11, nil, nil]], [65, [42, nil, nil], [99, nil, nil]]],
W = [w(1, 1), w(2, 2), w(3, 4), w(4, 1)],
M = 4.
最后,您可以定义主谓词以获取树宽:
tree_width(Tree, Width) :-
get_widths(Tree, 1, [], Widths),
max_width(Widths, Width).
示例:
?- tree(T), tree_width(T,W).
T = [12, [8, [5, [2, nil, nil], nil], [11, nil, nil]], [65, [42, nil, nil], [99, nil, nil]]],
W = 4.
备注:为清楚起见,我选择将对表示为 w(Level,Width)
。但是,Prolog 的约定是将这样的对表示为 Level-Width
。