web-dev-qa-db-ja.com

ツリーデータ構造内のノードの総数?

各ノードの深さがLレベルのツリーデータ構造がありますabout Nノード。ツリー内のノードの総数を計算したいと思います。これを行うには(私は思う)、子を持つノードの割合を知る必要があります。

Nにおけるリーフノードと非リーフノードのこの比率の正しい用語は何ですか?

3つのノードの総数を計算するための式は何ですか?

更新誰かが答えの1つで分岐係数に言及しましたが、その後消えました。これが私が探していた言葉だったと思います。では、数式は分岐係数を考慮に入れるべきではありませんか?

更新正確な数値ではなく、架空のデータ構造についての見積もりを言うべきでした!

16
tpower

わかりました。各ノードには約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]
              |
             /|\
            / | \
28
Toon Krijthe

最初の答えのタイプミスを修正するだけです。深さLのツリーのノードの総数は(N ^(L + 1)-1)/(N-1)...(つまり、Lの累乗)です。 Lだけでなく+1)。

これは次のように表示できます。まず、私たちの定理を取ります:

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が残ります。これは右側であるため、初期の等式は真です。

12
Timbo

深さLのノード数の計算式は次のとおりです。(ルートノードがN個ある場合)

NL

すべてのノードの数を計算するには、すべてのレイヤーに対してこれを行う必要があります。

for depth in (1..L)
    nodeCount += N ** depth

ルートノードが1つしかない場合は、Lから1を引き、ノードの総数に1を加えます。

1つのノードで葉の量が平均的な場合と異なる場合、これは数に大きな影響を与える可能性があることに注意してください。ツリーの上位にあるほど、影響は大きくなります。

 * * * N ** 1 
 *** *** *** N ** 2 
 *** *** *** *** *** *** *** *** *** N ** 3 

これはコミュニティウィキなので、私の恐ろしい代数を自由に変更してください。

1
David Grant

ツリーがおよそfullである場合、つまり、最後の2つを除いて、すべてのレベルに子の完全な補完がある場合、N ^(L-2)とN ^(L-1)の葉の間にあります。ノードとN ^(L-1)ノードとN ^ Lノードの合計。

ツリーがいっぱいでない場合、完全に不均衡なツリーには1つのリーフノードがありますが、任意に多くの親があるため、リーフノードの数を知っていても役に立ちません。

「各ノードには約N個のノードがある」というステートメントはどれほど正確かと思います。平均分岐係数がわかっている場合は、ツリーの予想サイズを計算できる可能性があります。

内部ノードに対する葉の比率を見つけることができ、子の平均数がわかっている場合は、これを(n * ratio)^ N = nとして概算できます。これはあなたにあなたの答えを与えることはありませんが、私よりも優れた数学を持っている誰かが、Lをこの方程式に挿入してあなたに何か溶けるものを与える方法を理解できるかどうか疑問に思います。

それでも、正確に知りたい場合は、ツリーの構造を繰り返し処理し、ノードを数える必要があります。

1
HenryR

Knuthの推定量[1]、[2]は 点推定 であり、すべてのノードを通過する必要がなく、ツリーのバランスが取れていなくても、任意の有限ツリー内のノードの数をターゲットにします。 Knuthの推定量は、不偏推定量の一例です。 Knuthの推定量の期待値は、ツリー内のノードの数になります。そうは言っても、問題のツリーが不均衡な場合、Knuthの推定量は大きな分散を持つ可能性がありますが、あなたの場合、各ノードには約N個の子があるため、Knuthの推定量の分散は大きすぎないはずです。この推定量は、ブルートフォース検索の実行にかかる時間を測定しようとする場合に特に役立ちます。

以下の関数では、すべてのツリーがリストのリストとして表されていると想定します。たとえば、_[]_は単一ノードのツリーを示し、_[[],[[],[]]]_は5ノードと3リーフのツリーを示します(ツリー内のノードは左と1対1で対応しています)ブラケット)。以下の関数は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個のノードがあります)。

  1. 検索ツリーサイズの見積もり。 http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.129.5569&rep=rep1&type=pdf

  2. バックトラックプログラムの効率の見積もり。ドナルドE.クヌース http://www.ams.org/journals/mcom/1975-29-129/S0025-5718-1975-0373371-6/S0025-5718-1975-0373371-6.pdf

0
Joseph Van Name

木の深さしかわからない場合は、合計サイズを計算するための唯一のオプションは、それらを調べて数えることです。

0
Mark Pim