Zum Inhalt springen

Union-Find-Struktur

aus Wikipedia, der freien Enzyklopädie
Dies ist eine alte Version dieser Seite, zuletzt bearbeitet am 17. September 2006 um 16:34 Uhr durch 82.119.169.206 (Diskussion). Sie kann sich erheblich von der aktuellen Version unterscheiden.

Eine Union-Find-Datenstruktur verwaltet die Partition einer Menge. Der abstrakte Datentyp wird durch die Menge der drei Operationen {Union, Find, Make-Set} gebildet. Union-Find-Strukturen dienen zur Verwaltung von Zerlegungen in disjunkte Mengen. Dabei bekommt jede Menge der Zerlegung ein kanonisches Element zugeordnet, dieses dient als Name der Menge. Union vereinigt zwei solche Mengen, Find(x) bestimmt das kanonische Element derjenigen Menge, die x enthält und Make- Set erzeugt eine Einermenge {x} mit dem kanonischen Element x.

Definition

Eine endliche Menge sei in die disjunkten Klassen partitioniert:

mit .

Zu jeder Klasse wird ein Repräsentant ausgewählt. Die zugehörige Union-Find-Struktur unterstützt die folgenden Operationen effizient:

  • Init(): Initialisiert die Struktur und bildet für jedes eine eigene Klasse mit als Repräsentant.
  • Union(, ): Vereinigt die beiden Klassen, die zu den beiden Repräsentanten und gehören, und bestimmt zum neuen Repräsentanten der neuen Klasse.
  • Find(): Bestimmt zu den eindeutigen Repräsentanten, zu dessen Klasse gehört.

Implementierung

Eine triviale Implementierung speichert die Zugehörigkeiten zwischen den Elementen aus und den Repräsentanten in einem Array. Für kürzere Laufzeiten werden jedoch in der Praxis Mengen von Bäumen verwendet. Dabei werden die Repräsentanten in den Wurzeln der Bäume gespeichert, die anderen Elemente der jeweiligen Klasse in den Knoten darunter.

  • Union(, ): Hängt die Wurzel des niedrigeren Baumes als neues Kind unter die Wurzel des höheren Baumes (gewichtete Vereinigung). Falls nun Kind von ist, werden und vertauscht. Für eine effiziente Implementierung werden die Baumhöhen in den Wurzeln mitgeführt.
  • Find(): Wandert vom Knoten aus den Pfad innerhalb des Baumes nach oben bis zur Wurzel und gibt diese als Ergebnis zurück.

Pfadkompression

Um spätere Find() Suchvorgänge zu beschleunigen, versucht man die Wege vom besuchten Knoten zur zugehörigen Wurzel zu verkürzen.

- maximale Verkürzung

Nach dem Ausführen von Find() werden alle Knoten auf dem Pfad von zur Wurzel direkt unter die Wurzel gesetzt.

Da man aber doppelte Durchläufe in dem Baum vermeiden will, sind folgende Verfahren geeigneter:

- Aufteilungsmethode (splitting)

Während des Durchlaufes lässt man jeden Knoten auf seinen bisherigen Großvater zeigen (falls vorhanden); damit wird ein durchlaufender Pfad in zwei der halben Länge zerlegt.

- Halbierungsmethode (halving)

Während des Durchlaufes lässt man jeden zweiten Knoten auf seinen bisherigen Großvater zeigen.

Diese Methoden haben beide dieselben amortisierten Kosten wie die oberste Kompressionsmethode (Knoten unter die Wurzel schreiben). Alle Kompressionsmethoden beschleunigen zukünftige Find()-Operationen.

Laufzeiten

Union-Find-Datenstrukturen ermöglichen die Ausführung der obigen Operationen mit den folgenden Zeitkomplexitäten:

Triviale Implementierung:

Implementierung mit Bäumen ():

  • mit gewichteter Vereinigung: Union , Find
  • mit gewichteter Vereinigung, Pfadkompression, worst-case (Find und Union):
  • mit gewichteter Vereinigung, Pfadkompression, Folge von m Operationen (Find und Union):