BSTと2つの整数aとb(a < b)が与えられた場合、どのようにしてノードの数を見つけることができますか?a <ノード値< b、O(log n)?範囲内の範囲内のノードの数0(LogN)内のバイナリ検索ツリー
LogN時間でaとbの位置を簡単に見つけることができますが、通過を行わずにノードを数える方法はO(n)ですか?
BSTと2つの整数aとb(a < b)が与えられた場合、どのようにしてノードの数を見つけることができますか?a <ノード値< b、O(log n)?範囲内の範囲内のノードの数0(LogN)内のバイナリ検索ツリー
LogN時間でaとbの位置を簡単に見つけることができますが、通過を行わずにノードを数える方法はO(n)ですか?
に、また、その値よりも小さい(または、で言及異なるツリー設計のためにあるツリー内の値の数のカウントを維持下の脚注、左のサブツリーのノード)。
次に、値a
を含むノードを見つけます。このノードに格納されているa
より小さい値の数を取得します。このステップはLog(n)です。
ここで、値b
を含むノードを見つけます。このノードに格納されているb
より小さい値の数を取得します。このステップもLog(n)です。
2つのカウントを差し引くと、a
とb
の間のノードの数があります。この検索の合計複雑度は2 * Log(n)= O(Log(n))です。
this videoを参照してください。教授はここであなたの質問をSplay Treesを使って説明します。
"Splay Treesのノードは、左右のサブツリーの要素の数を自動的に設計によって自動的に保持します"これは私にとってのニュースです... [ splay tree](https://en.wikipedia.org/wiki/Splay_tree)にはそのプロパティがありませんAFAIK –
@NiklasB:私は[ここ](https://m.youtube.com/watch? v = G5QIXywcJlY)。これは、彼がSplay Treeを記述した方法です。私はWikipediaのページにその定義がないことに同意します。 – displayName
@NiklasB .:回答を一般的かつ正確に保つため、私もそれを更新しました。 – displayName
アイデアは簡単です。
時間の複雑さは、なぜそれがO(n)
ではないことをあなたの質問のためにO(height + number of nodes in range)
...
になります。
ツリー内のノードの数であるツリー全体をトラバースしていないためです。親のデータに従って必要なサブツリーをたどるだけです。
擬似コード
int findCountInRange(Node root, int a, int b){
if(root==null)
return 0;
if(root->data <= a && root->data >= b)
return 1 + findCountInRange(root->left, a, b)+findCountInRange(root->right, a, b);
else if(root->data < low)
return findCountInRange(root->right, a, b);
else
return findCountInRange(root->left, a, b);
}
クエリ範囲がツリーのすべての要素をカバーする場合はどうなりますか?あなたのアルゴリズムは確かにOmega(n) –
修正です。複雑さはO(高さ+範囲内のノード数)になります。 – FallAndLearn
aとbがそれぞれツリーの最下位ノードと最上位ノードの場合はどうなりますか?私はそれらのノードO(nlog)を探索するいくつかの数学的特性を逃していますか? – Pinhead
ストアアレイ内のBSTのINORDERトラバーサル(それがソートされます)。 'a'と 'b'を検索すると、log(n)時間がかかり、そのインデックスが取得され、その違いが得られます。これは範囲 'a'のノードの番号を 'b'に与えます。
あなたのバイナリ検索ツリーの各ノードにはスペースの複雑さはO(n)
InorderトラバーサルはO(n)時間かかるでしょう。あなたはそれを数えていません。 – FallAndLearn
はい!これは一度構築されますが、クエリの結果は常にO(log n) –
なぜ、各ノードにその下のサブツリー内のノードの数で変数を保持させるだけでいいのですか? – aioobe
LogNの時間でN個のものを数えることはできません。ツリーを構築したときに情報が既に作成されている必要があります。 – xaxxon
拡張検索ツリー? – Pinhead