タグ付けされた質問 「search-trees」

効率的なアクセスのためにソートされたデータを格納するために使用されるデータ構造のクラスである検索ツリーに関する質問。

1
範囲合計問題のセグメントツリー実装の時間の複雑さの証明
のサブ配列の合計を見つけるためにセグメントツリーを使用できることを理解しています。そして、ここのチュートリアルによれば、これはO(log n )時間で実行できます。あAAO(ログn )O(log⁡n)\mathcal{O}(\log n) ただし、クエリ時間が実際にことを証明することはできません。このリンク(および他の多くのリンク)は、各レベルで処理されるノードの最大数が4であることを証明できるため、O(4 log n )= O(log n )であると述べています。O(ログn )O(log⁡n)\mathcal{O}(\log n)444O(4ログn )= O(ログn )O(4log⁡n)=O(log⁡n)\mathcal{O}(4 \log n) = \mathcal{O}(\log n) しかし、おそらく矛盾によって、どうやってこれを証明するのでしょうか? もしそうなら、もし私たちがより高次元の配列の範囲の合計にセグメントツリーを使うとしたら、証明はどのように拡張されるでしょうか? たとえば、元の行列を4つの象限(線形配列の2分の1間隔と同様)に分割して、象限セグメントツリーを構築してサブ行列の合計を見つけることを考えることができますが、その証拠は私にはわかりません。

1
範囲更新+バイナリインデックスツリーを使用した範囲クエリ
範囲のクエリと範囲の更新の両方を処理するためにバイナリインデックス付きツリー(fenwickツリー)をどのように変更できるかを理解しようとしています。 次のソースを見つけました: http://kartikkukreja.wordpress.com/2013/12/02/range-updates-with-bit-fenwick-tree/ http://programmingcontests.quora.com/Tutorial-Range-Updates-in-Fenwick-Tree http ://apps.topcoder.com/forums/?module = Thread&threadID = 756271&start = 0&mc = 4#1579597 しかし、それらすべてを読んでも、2番目のバイナリインデックス付きツリーの目的や、それが何をするのか理解できませんでした。 誰かがバイナリインデックス付きツリーがこれらを処理するためにどのように変更されるかを私に説明してもらえますか?

2
確率的検索データ構造は役に立ちますか?
SkipListは、バランス調整されたツリーと同じ境界を提供し、再調整が不要であるという利点があります。SkipListはランダムコインフリップを使用して構築されるため、SkipListの構造が十分に「バランス」されている限り、これらの境界は保持されます。特に、一定のc > 0に対して1 / n cの確率で、要素を挿入した後にバランスの取れた構造が失われる可能性があります。O (ログn )O(log⁡n)O(\log n)1 / nc1/nc1/n^cc > 0c>0c>0 永久に実行される可能性のあるWebアプリケーションのストレージバックエンドとしてスキップリストを使用するとします。したがって、いくつかの多項式の操作の後、SkipListのバランスのとれた構造は失われる可能性が非常に高くなります。 私の推論は正しいですか?そのような確率的検索/ストレージデータ構造には実用的なアプリケーションがありますか?そうであれば、上記の問題をどのように回避しますか? 編集:私は、(クラシックな)ランダム化されたSkipListに比べて実装がはるかに複雑な、SkipListの確定的なバリアントがあることを認識しています。

3
対数対二重対数時間の複雑さ
使用する際に実際のアプリケーションでは、具体的な利点がありますの代わりにO(ログ(N ))のアルゴリズム?O(ログ(ログ( n ))O(ログ⁡(ログ⁡(ん))\mathcal{O}(\log(\log(n))O(ログ(n ))O(ログ⁡(ん))\mathcal{O}(\log(n)) これは、従来の二分探索木実装の代わりに、たとえばvan Emde Boas木を使用する場合です。ただし、たとえば、場合、最良の場合、対数アルゴリズムは対数アルゴリズムよりも(約)5倍優れています。また、一般的に、実装はよりトリッキーで複雑です。n &lt; 106ん&lt;106n < 10^6555 私が個人的にVEBツリーよりもBSTを好むとすれば、どう思いますか? 簡単にそれを示すことができます: ∀ N &lt; 106。ログ んログ(ログ( n ))&lt; 5.26146∀ん&lt;106。 ログ⁡んログ⁡(ログ⁡(ん))&lt;5.26146\qquad \displaystyle \forall n < 10^6.\ \frac{\log n}{\log(\log(n))} < 5.26146

2
複雑度
分割操作は、複雑度 AVLツリーに実装できますO(logn)O(log⁡n)O(\log n)か?このトピックに関する記事または特定の情報へのリンクに興味があります。 分割操作は、キーに基づいて、AVLツリーを2つの派生AVLツリーに分割します。派生したツリーの1つは、すべてのキーが元のキーよりも小さいすべての頂点を含み、2番目のツリーは残りの頂点を含みます。 これはO(log2n)O(log2⁡n)O(\log^2 n)時間で実行できることを知っています。複雑さ実装へのリンクはO(log2n)O(log2⁡n)O(\log^2 n)次のとおりです。https: //code.google.com/p/self-balancing-avl-tree/ また、2つのAVLツリーをマージして、O(logn)O(log⁡n)O(\log n)時間で、一方のツリーのキーがすべて他方のキーよりも小さくなるようにする方法も知っています。以下は、複雑度実装O(logn)O(log⁡n)O(\log n)です。 def Merge(l, r) { if (!l || !r) return l ? l : r; if (l-&gt;h &lt;= r-&gt;h) r-&gt;l = Merge(l, r-&gt;l), Rebalance(r); else l-&gt;r = Merge(l-&gt;r, r), Rebalance(l); }

3
線形時間の最悪の場合をどのようにカウントするのですか?
この質問とこの質問は私に少し考えさせられました。長さの配列をソートするためnnnとkkk中のユニークな要素、我々は、配列内の値の数を格納できるようにする必要があります。いくつかの提案がありますが、最悪の場合線形時間でこれを行う方法を探しています。すなわち:O(n+klogk)O(n+klog⁡k)O(n + k \log k) リストの指定されたのを有する要素別個の要素、タプルのリストを決定すべての固有の要素よう要素の数であるで。AAAnnnkkkU={(xi,ci)}kU={(xi,ci)}kU = \{(x_i, c_i)\}^kxi∈Axi∈Ax_i \in Acicic_ixixix_iAAA 私がこれまでに提案してきた(失敗した)アイデアの一部を以下に示します。 平衡型二分探索木 -これを使用すると、O(logk)O(log⁡k)O(\log k)をツリーに挿入して値を増やす必要があります。挿入後、O(k)O(k)O(k)でツリートラバーサルを実行できます。したがって、合計時間がO(nlogk)O(nlog⁡k)O(n \log k)これは遅すぎます。 ハッシュマップ -これにより、O(1)O(1)O(1) 予想される挿入、つまりO(n)O(n)O(n) 予想される時間を取得できます。ただし、これはまだO(n)O(n)O(n)最悪のケースではありません。 空の空間マッピングAAA最小要素と最大要素を見つけます。この範囲をカバーするのに十分なメモリを割り当てます(ただし、初期化しません)。このメモリを基本的にハッシュマップとして使用し、ランダムハッシュを含めて、破損したメモリにアクセスしないようにします。この戦略には問題があります。(1)失敗する可能性が非常に低い確率論的ですが、保証されていません。このようなメモリを使用すると、浮動小数点または整数の制約に制限されます。 連想配列 - ハッシュマップやBSTと同様に、使用できる他の多くの連想配列がありますが、これらの制約に一致するものは見つかりません。 たぶん私が見逃している明らかな方法があるかもしれませんが、それは潜在的に不可能かもしれないと私は思います。あなたの考えは何ですか?

1
挿入と削除が一方的である場合の効率的な検索のためのデータ構造
の要素を格納するためのデータ構造が必要 です。各要素は異なる時間関連付けられてい 。 は変動し、理論的な上限がありますが、これは通常使用されるものよりも桁違いに大きくなります。んんnt私t私t_iんんn 私のアプリケーションを通して、私はそれを保証することができます: 挿入された要素は、既存のすべての要素より常に新しいものです。つまり、時間関連付けられた要素が挿入された場合、ます。要素は1つずつ挿入されます。tˇtˇ\check{t}tˇ&gt; t私∀ I∈ 1 、... 、n個tˇ&gt;t私∀私∈1、…、ん\check{t}>t_i ∀ i ∈ {1,…,n} 最も古い要素のみが削除されます。つまり、要素が削除された場合、ます。削除は主に1つずつ行われますが、誤って格納された要素の割合が1未満である限り、要素の削除が遅れても直接的な害はありません。jjjtj&lt; t私 ∀ I∈{1、...、N}∖{J}tj&lt;t私 ∀私∈{1、…、ん}∖{j}t_j < t_i ~∀ i ∈ \lbrace 1,…,n \rbrace \setminus \lbrace j \rbrace 挿入と削除を除いて、私がする必要がある唯一のことは、、ある時間の2つの隣接する要素を見つけること。言い換えると、t_j &lt;\ tilde {t} &lt;t_kおよび∄l {\ {1、…、n \}:t_j &lt;t_l &lt;t_k となるような2つの要素jと kを見つける必要があります。t〜t〜\tilde{t}分私t私&lt; t〜&lt; 最大私t私分私t私&lt;t〜&lt;最高私t私\min\limits_i t_i < \tilde{t} < …


2
AVLの中央値。AVLを活用する方法?
これが私の質問の出典です。 自己均衡ツリー(AVL)を指定して、中央値を返すメソッドをコーディングします。 (中央値:データサンプルの上半分と下半分を区切る数値。例:系列が 2、7、4、9、1、5、8、3、6 中央値は5です。) 私は次の解決策を提供できます: 指定されたツリーをトラバースし、要素の数を返します。 木をトラバース n / 2 + 1(n奇数の場合)して、順番にツリーウォークを適用します。値n / 2 + 1番目の要素は、中央値です。 しかし、二分探索木でそれを行うことができますか?AVLに適したアルゴリズムはありますか?


2
私たちはより良いことができますか
この質問に対する答えは「いいえ」であると、私は(愚かにも判明しました)確信しています。なぜ私は尋ねるのですか? それは、EPFLの並列プログラミングコースのAleksandar Prokopec博士が、さまざまな特性を主張するデータ構造を導入しているためです。これらの特性は保持している場合、そうです、私により良いでバランスの取れたバイナリツリーを構築することが可能でなければならないこと時間。O ( nログn )O(んログ⁡ん)O(n\log n) 私はこれを信じていないので、私の考えのどこに欠陥があるのだろうと思います。 データ構造は、conc-treeリストです。標準形式では、通常のバイナリツリーのように見えconcat、ノードの左右のサブツリーの高さが2以上異なることがないことを保証する操作が付属しています。予想通りconcat、複雑さはです。O (ログn )O(ログ⁡ん)O(\log n) しかし、リストと呼ばれるコンクツリーリストのビルダーバリアントがありAppendます。このバリアントは、複数のサブツリーで一時的な高さの違いを可能にします。このバリアントでは、償却済み時間の追加が要求されます。O (1 )O(1)O(1) そのため、要素を追加すると複雑さが必要になるようです。んんnO (n )O(ん)O(n) ただし、このバリアントの特徴は、が2の累乗であるときは常に、完全にバランスのとれた二分木(これまでに挿入されたすべての要素を含む)になることです。したがって、一時的な不均衡は許容されますが、ツリーは2挿入のすべてのパワーで均衡になります。んんn このバリアントでは、ノードと呼ばれる新しいクラスのノードAppendが導入され、サブツリーの高さが1つ以上異なることが許可されているノードです。ただし、挿入ごとに、このような一時ノードはすべて削除されます。2k2k2^k Wikipediaのページのページは、(基本的なデータ構造の記述と見かなり簡潔なアルゴリズムを説明しappend、特定のメソッドを)。 したがって、が2の累乗の場合、要素を挿入するためのコストはあり、バランスのとれたバイナリツリーを構築しました。またはそうです。んんnO (n )O(ん)O(n) で別の質問私は、特定の値のためのアルゴリズムのためのステップ数を述べることができる場合、私は効果的に」尋ねのために例えば、、整数である、私は複雑さを述べるできるようにするには、この十分ですすべての値?」んんnn =2kん=2kn = 2^kkkkんんn Yuval Filmusの答えから、答えは「いいえ」であることがわかりますが、「多くの場合、はで単調であると予想されます。その場合、控除は成立します。」TTTんんn したがって、この場合、要素の挿入に複雑さあり、要素ごとに平衡バイナリツリーがある場合、このコンクツリーバリアントアプローチで平衡バイナリツリーを構築するコストは。んんnO (n)O(ん)O(n)2k2k2^kO (n )O(ん)O(n) ここで何が問題になっていますか?正直に言うと、このバリアントに対して要求された償却済み追加時間がわかりません。多くの場合、挿入にはコストがかかりますが、一時ノードで何が起こっているかを見ると、全体的な挿入コストは償却されたように見え。O (1 )O(1)O(1)O (1 )O(1)O(1)AppendO (ログん)O(ログ⁡ん)O(\log n) これが当てはまる場合、バランスの取れたバイナリツリーを構築すると、驚くほどのコストがかかります。O (nログn )O(んログ⁡ん)O(n\log n) 長い質問で申し訳ありませんが、問題のアルゴリズムについて詳しく説明していません。代わりに、ウィキペディアを見回してください。

4
最近アクセスした要素への高速アクセスと最悪の複雑さを持つバイナリツリー構造はありますか?
スプレーツリーのアイデアは、頻繁にアクセスされる要素を一番上に移動するので非常に優れています。これにより、多くのアプリケーションでかなりの速度を上げることができます。欠点は、最悪の場合、操作が複雑になる可能性があることです。(ただし、少なくとも操作を実行すると、償却済みの境界は。)O(n)O(n)O(n)O(nlogn)O(nlog⁡n)O(n\log n) nnn 両方を備えた自動調整検索ツリー構造はありますか?最近アクセスした要素を優先し、1回の操作で複雑さが最悪ですか?O(logn)O(log⁡n)O(\log n)

1
重みのバランスが悪くなることを回避できるバイナリ検索ツリーのデータ構造はありますか?
これは、「すべてのRed-Blackツリーのバランスが取れているわけではないのですか?」および「AVLツリーのウェイトバランスが取れていないのですか?」のフォローアップの質問です。\def\le{\leqslant}\def\ge{\geqslant} 定義:ルート付きツリーと頂点v \ in V(T)の場合、L_T(v)をvからの左サブツリー内のノード数、N_T(v)をルート付きサブツリー内のノード数とするで、V。Tは\ mu -balancedであり、0 \ le \ mu \ le \ frac {1} {2}であると言います。すべてのノードv \ in V(T)で不等式 \ mu \ le \ frac {L_T(v )+ 1} {N_T(v)+ 1} \ le 1-\ mu が成り立ち、\ muが最小の場合、この不等式の支配を受けます。TTTv∈V(T)v∈V(T)v \in V(T)LT(v)LT(v)L_T(v)vvvNT(v)NT(v)N_T(v)vvvTTTμμ\mu0⩽μ⩽120⩽μ⩽120 \le \mu \le \frac{1}{2}v∈V(T)v∈V(T)v \in V(T)μ⩽LT(v)+1NT(v)+1⩽1−μμ⩽LT(v)+1NT(v)+1⩽1−μ \mu \le \frac{L_T(v) + 1}{N_T(v) …
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.