2016-05-03 12 views
3

Gegeben eine BST und zwei ganze Zahlen "a" und "b" (a < b), wie können wir die Anzahl der Knoten so finden, dass ein < Knotenwert < b, in O (log n)?Anzahl der Knoten innerhalb des Bereichs im binären Suchbaum in O (LogN)

Ich weiß, man kann leicht die Position von a und b in LogN Zeit finden, aber wie man die Knoten dazwischen zählt, ohne eine Traversierung zu machen, die O (n) ist?

+1

Warum lassen Sie nicht einfach jeden Knoten eine Variable mit der Anzahl der Knoten im darunterliegenden Teilbaum verwalten? – aioobe

+3

Sie können N Dinge nicht in LogN Zeit zählen - Sie müssen die Informationen bereits erstellt haben, als Sie den Baum erstellt haben. – xaxxon

+0

Erweiterte Suchbäume? – Pinhead

Antwort

5

In jedem Knoten Ihres binären Suchbaumes, auch Zählung der Anzahl der Werte im Baum halten, die kleiner als ihr Wert (oder für einen anderen Baumentwurf erwähnte in die Fußnote unten, die Knoten in seinem linken Teilbaum).

Suchen Sie zuerst den Knoten mit dem Wert a. Holen Sie sich die Anzahl der Werte kleiner als a, die in diesem Knoten gespeichert wurde. Dieser Schritt ist Log (n).

Suchen Sie nun den Knoten mit dem Wert b. Erhalten Sie die Anzahl der Werte kleiner als b, die in diesem Knoten gespeichert sind. Dieser Schritt ist auch Log (n).

Subtrahieren Sie die zwei Zähler und Sie haben die Anzahl der Knoten zwischen a und b. Die gesamte Komplexität dieser Suche ist 2 * Log (n) = O (Log (n)).


Siehe this video. Der Professor erklärt Ihre Frage hier mit Splay Trees.

+0

"Die Knoten in Splay Trees behalten die Anzahl der Elemente im linken und rechten Teilbaum automatisch, von Entwurf" Das ist neu für mich ... Die übliche Formulierung von [ splay trees] (https://en.wikipedia.org/wiki/Splay_tree) hat diese Eigenschaft nicht AFAIK –

+0

@NiklasB .: Ich habe Splay Trees von [hier] studiert (https://m.youtube.com/watch? v = G5QIXywcJlY). So beschrieb er den Splay Tree. Ich stimme zu, dass die Wikipedia-Seite diese Definition nicht enthält. – displayName

+0

@NiklasB .: Um die Antwort allgemein und korrekt zu halten, habe ich sie auch aktualisiert. – displayName

-1

Die Idee ist einfach.

  1. Die BST ausgehend von der Wurzel durchlaufen.
  2. Überprüfen Sie für jeden Knoten, ob er in Reichweite liegt. Wenn es im Bereich liegt, dann zähle ++. Und wiederkehren für beide seiner Kinder.
  3. Wenn der aktuelle Knoten kleiner als der niedrige Wert des Bereichs ist, dann wiederholen Sie für das rechte Kind, andernfalls wiederholen Sie für das linke Kind.

Zeitkomplexität O(height + number of nodes in range) sein ..

Für Ihre Frage, warum es nicht O(n) ist.

Da wir nicht den gesamten Baum durchlaufen, ist dies die Anzahl der Knoten im Baum. Wir durchlaufen nur den erforderlichen Teilbaum gemäß den Daten des Elternteils.

Pseudocode

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); 

} 
+1

Was ist, wenn der Abfragebereich alle Elemente in der Struktur abdeckt?dann ist Ihr Algorithmus in der Tat Omega (n) –

+0

Korrektur. Die Komplexität ist O (Höhe + Anzahl der Knoten im Bereich). – FallAndLearn

+0

Was ist, wenn a und b die niedrigsten bzw. höchsten Knoten in Baum sind? Fehle mir eine mathematische Eigenschaft, die das Erforschen dieser Knoten O (nlog) macht? – Pinhead

0

speichern die Inorder Traversierung von BST in Array (es wird sortiert werden). Die Suche nach 'a' und 'b' dauert log (n) mal und sie erhalten ihren Index und nehmen den Unterschied. Dies gibt die Anzahl der Knoten im Bereich 'a' bis 'b'.

Raum Komplexität O (n)

+1

Inverses Traversieren dauert O (n) Zeit. Das zählst du nicht. – FallAndLearn

+0

Ja! Dies wird nur einmal erstellt, aber das Abfrageergebnis wird immer 0 (log n) sein. –

Verwandte Themen