【问题标题】:Number Of Ways To Traverse a Binary Tree遍历二叉树的方法数
【发布时间】:2016-01-09 09:09:48
【问题描述】:

考虑n个节点的二叉树。例如,考虑以下树:

     1
   /   \
  2     3
 / \   / \
4   5 6   7
           \
            8

我可以用多少种不同的方式从根(顶部)节点开始完全遍历树,并且只移动到与已经访问过的节点直接连接的未访问节点(即我可以从 1 到 2 到4 然后到 3)?

【问题讨论】:

  • @sharky 你能详细说明一下吗?我看过这个页面,在那里我找不到我的问题的答案。
  • 您的意思是探索次数,而不是遍历次数,因为遍历意味着遵循路径?例如如果您访问过 {1, 2},您可以访问 4,5 或 3?
  • @svs 是的,我的意思是如果你访问过 {1, 2} 你可以访问 4,5, 或 3
  • 答案取决于n个以上。例如,只有左节点的二叉树只有一个枚举。

标签: algorithm tree binary-tree binary-search-tree


【解决方案1】:

在 Math Stack 交流中提问可能会更幸运。

您要求的是二叉树的线性扩展数,该二叉树被视为一个poset。虽然我看不到通用公式,但可以递归地解决这个问题:

求遍历左右子树的方式数(空树以1方式简单遍历)。调用这些 T_L 和 T_R。令#L 和#R 分别为左树和右树的基数(大小)。那么遍历整棵树的方式数为

T_L * T_R * (#L + #R 选择#L)

因为我们可以用 T_L 方式遍历左树,用 T_R 方式遍历右树(与我们如何遍历右树无关),并且我们可以在 (#L + #R 选择 #L ) 方式。

在你的例子中,有两种遍历左树的方式,三种遍历右树的方式,(7选3)是35,所以有2*3*35 = 210种遍历树的方式。

【讨论】:

  • #R选择#L中的选择是什么?
  • 这是二项式系数,(n 选择 k) 是从 n 个可区分事物中选择 k 个事物的方式的数量。公式是 n!/(k! * (n-k)!) 其中 !表示阶乘
【解决方案2】:

使用 Prolog 对 @deinst 的答案进行编程验证:

traverse([], []) :- !.
traverse(F, [N|P]) :-
    % select a frontier node from F
    select(t(N,C), F, Rem),
    % append all new accessible children to the frontier
    append(C, Rem, NewF),
    % traverse the remaining set
    traverse(NewF, P).

tree(X) :-
    X = t(1,[t(2,[t(4,[]), t(5,[])]),t(3,[t(6,[]), t(7,[t(8,[])])])]).

do :-
    tree(X),
    findall(P, (traverse([X], P), write_ln(P)), Ps),
    length(Ps, L),
    write_ln(L).

这确实返回了 210 种可能性,正如您为示例树所建议的那样。

?- do.
[1,2,4,5,3,6,7,8]
[1,2,4,5,3,7,8,6]
[1,2,4,5,3,7,6,8]
[1,2,4,3,6,7,8,5]
[1,2,4,3,6,7,5,8]
[1,2,4,3,6,5,7,8]
[1,2,4,3,7,8,6,5]
[1,2,4,3,7,8,5,6]
[1,2,4,3,7,6,8,5]
...
[1,3,2,7,6,4,8,5]
[1,3,2,7,6,4,5,8]
[1,3,2,7,6,5,8,4]
[1,3,2,7,6,5,4,8]
210
true.

【讨论】:

    猜你喜欢
    • 2021-01-12
    • 2012-01-01
    • 2022-11-11
    • 1970-01-01
    • 2021-11-17
    • 2021-07-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多