我有一个L级深度的树数据结构,每个节点都有约 N个节点。我想计算树中的节点总数。要做到这一点(我认为),我需要知道有孩子的节点的百分比。
N?
中叶节点与非叶节点的比率的正确术语是什么?计算三个节点中的总节点数的公式是什么?
更新有人在其中一个答案中提到分支因子,但随后就消失了。我认为这是我一直在寻找的术语。那么公式是否应该考虑分支因子?
更新我应该对假设的数据结构做出估计,而不是确切的数字!
答案 0 :(得分:25)
好的,每个节点有大约N个子节点,树的深度为L级。
With 1 level, the tree has 1 node.
With 2 levels, the tree has 1 + N nodes.
With 3 levels, the tree has 1 + N + N^2 nodes.
With L levels, the tree has 1 + N + N^2 + ... + N^(L-1) nodes.
节点总数为(N ^ L-1)/(N-1)。
好的,只是一个小例子,它是指数的:
[NODE]
|
/|\
/ | \
/ | \
/ | \
[NODE] [NODE] [NODE]
|
/|\
/ | \
答案 1 :(得分:8)
只是为了纠正第一个答案中的拼写错误:深度为L的树的节点总数为(N ^(L + 1)-1)/(N-1)...(即,功率L + 1而不仅仅是L)。
这可以显示如下。首先,采用我们的定理:
1 + N ^ 1 + N ^ 2 + ... + N ^ L =(N ^(L + 1)-1)/(N-1)
将两边乘以(N-1):
(N-1)(1 + N ^ 1 + N ^ 2 + ... + N ^ L)= N ^(L + 1)-1。
展开左侧:
N ^ 1 + N ^ 2 + N ^ 3 + ... + N ^(L + 1) - 1 - N ^ 1 - N ^ 2 - ... - N ^ L。
所有项N ^ 1到N ^ L都被取消,留下N ^(L + 1) - 1.这是我们的右手边,所以初始相等是正确的。
答案 2 :(得分:1)
计算深度为L的节点数量的公式为:(假设有N个根节点)
名词→
要计算每个层需要执行此操作的所有节点的数量:
for depth in (1..L)
nodeCount += N ** depth
如果只有一个根节点,则从L中减去1并将1添加到总节点数。
请注意,如果在一个节点中叶子的数量与平均情况不同,则会对您的数量产生很大影响。在树中越往上越有影响力。
* * * N ** 1 *** *** *** N ** 2 *** *** *** *** *** *** *** *** *** N ** 3
这是社区维基,所以请随意修改我令人震惊的代数。
答案 3 :(得分:1)
如果你的树大约已经,那么除了最后两个之外,每个级别都有其完整的子级,那么你有N ^(L-2)和N ^(L- 1)叶节点和N ^(L-1)和N ^ L节点之间的总数。
如果你的树没有满,那么知道叶子节点的数量没有帮助,因为完全不平衡的树将有一个叶子节点但是任意多个父节点。
我想知道你的'每个节点有关N个节点'的说法有多精确 - 如果你知道平均分支因子,也许你可以计算树的预期大小。
如果您能够找到叶子与内部节点的比率,并且您知道平均子节点数,则可以将其近似为(n * ratio)^ N = n。这不会给你你的答案,但我想知道如果有一个比我更好的数学的人能找到一种方法将L插入这个等式并给你一些可溶的东西。
但是,如果你想要准确地知道,你必须迭代树的结构并随时计算节点。
答案 4 :(得分:0)
如果除了树的深度之外你什么都不知道,那么计算总大小的唯一选择就是计算它们。
答案 5 :(得分:0)
Knuth的估计量[1],[2]是point estimate,它以任意有限树中的节点数为目标,而无需遍历所有节点,即使树不平衡也是如此。 Knuth的估计量是无偏估计量的一个示例。 Knuth估计量的期望值将是树中的节点数。话虽如此,如果所讨论的树不平衡,则Knuth估计量的方差可能会很大,但是在您的情况下,由于每个节点大约有N个子代,因此我认为Knuth估计量的方差不会太大。当人们试图测量执行暴力搜索所需的时间时,此估算器特别有用。
对于以下功能,我们假定所有树都表示为列表列表。
例如,[]
表示具有单个节点的树,[[],[[],[]]]
表示具有5个节点和3个叶子的树(树中的节点与左侧一一对应。括号)。以下功能以GAP语言编写。
函数simpleestimate
为输出提供对树tree
中节点数的估计。 simpleestimate
背后的想法是,我们随机选择从树的根x_0到叶x_n的路径x_0,x_1,...,x_n。假设x_i具有a_i后继者。然后simpleestimate
将返回1 + a_1 + a_1 * a_2 + ... + a_1 * a_2 * ... * a_n。
point:=tree; prod:=1; count:=1; list:=[];
while Length(point)>0 do prod:=prod*Length(point); count:=count+prod; point:=Random(point); od;
return count; end;
函数estimate
将简单给出通过多次应用函数simpleestimate(tree)
samplesize
给出的估算值的算术平均值。
estimate:=function(samplesize,tree) local count,i;
count:=0;
for i in [1..samplesize] do count:=count+simpleestimate(tree); od;
return Float(count/samplesize); end;
示例:simpleestimate([[[],[[],[]]],[[[],[]],[]]]);
返回15
的同时
estimate(10000,[[[],[[],[]]],[[[],[]],[]]]);
返回10.9608
(树实际上有11个节点)。