sah ich dieses Beispiel in „Programming in Scala“ Kapitel 24 „Sammlungen in der Tiefe“. Dieses Beispiel zeigt zwei alternative Möglichkeiten, um einen Baum zu implementieren:Verkettung von Iteratoren
von
Traversable[Int]
erstreckt - hier die Komplexität derdef foreach[U](f: Int => U): Unit
wäreO(N)
.durch Erweitern
Iterable[Int]
- hier wäre die Komplexitätdef iterator: Iterator[Int]
wäreO(N log(N))
. Diese
ist es zu zeigen, warum es hilfreich wäre, zwei separate Züge zu haben, Traversable
und Iterable
.
sealed abstract class Tree
case class Branch(left: Tree, right: Tree) extends Tree
case class Node(elem: Int) extends Tree
sealed abstract class Tree extends Traversable[Int] {
def foreach[U](f: Int => U) = this match {
case Node(elem) => f(elem)
case Branch(l, r) => l foreach f; r foreach f
}
}
sealed abstract class Tree extends Iterable[Int] {
def iterator: Iterator[Int] = this match {
case Node(elem) => Iterator.single(elem)
case Branch(l, r) => l.iterator ++ r.iterator
}
}
die Umsetzung foreach
Bezug sie sagen:
ein ausgeglichener Baum nimmt im Baum proportional zur Anzahl der Elemente Zeit durchquert. Um dies zu sehen, der Ansicht, dass für einen ausgeglichenen Baum mit
N
Blätter werden SieN - 1
inneren Knoten der Klasse Niederlassung haben. So die Gesamtzahl der Schritte, um den Baum zu durchlaufen istN + N - 1
.
, die Sinn macht. :)
jedoch erwähnen sie, dass die Verknüpfung der beiden Iteratoren im iterator
Methode Zeitkomplexität von log(N)
hat, so dass die Gesamtkomplexität des Verfahrens wäre N log(N)
:
Jedes Mal, wenn ein Element erzeugt wird, durch einen verketteten Iterator, wie zum Beispiel
l.iterator ++ r.iterator
, muss die Berechnung einer Indirektion folgen, um den richtigen Iterator zu erhalten (entwederl.iterator
oderr.iterator
). Alles in allem macht daslog(N)
Indirektionen zu einem Blatt eines ausgewogenen Baumes mit N Blättern. So sind die Kosten alle Elemente eines Baumes Besuch ging von etwa bis2N
für dieforeach
Traversal-MethodeN log(N)
für die Traversal mititerator
.
????
Warum wird die Berechnung des verketteten Iterator Bedarf an einem Blatt der linken oder rechten Iterator zu bekommen?
Nicht sicher, dass ich Ihre Frage verstehe. Der verkettete Iterator muss ** jedes ** Element (Blatt) darunter erreichen. Jedes einzelne Blatt wird entweder vom "L-Zeichen" oder vom "R-Zeichen" geliefert. Die Anzahl der Umwege, die durchlaufen werden, um zu einem Blatt zu gelangen, ist genau die Tiefe des Baumes, wenn der Baum ausgeglichen ist. Also für N Blätter, Log (N) Traversalen, um zu irgendeinem bestimmten Blatt zu kommen. – jwvh
@jwvh meine Frage aktualisiert. Wie Sie sehen können, besucht die 'foreach' Methode auch jedes Blatt. Aber die Gesamtkomplexität ist nur O (N). Während die Komplexität von "Iterator" ist "O (N log (N))". Offensichtlich trägt die Anwendung von "++" auf "Iteratoren" zur Komplexität bei. – rapt