Prolog:查找二叉树中级别的节点数

时间:2021-06-01 07:57:56

标签: prolog

我应该求一棵二叉树的宽度,即同一层的最大节点数。

我应该定义: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]]]
 

enter image description here

结果是4,因为在第三层有4个节点(5, 11, 42, 99)

1 个答案:

答案 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

相关问题