Bäume, Suchbäume und Hash-Tabellen

Werbung
Grundlegende Datenstrukturen
Bäume, Suchbäume und Hash-Tabellen
Bäume, Suchbäume und Hash-Tabellen
Im folgenden Fokus auf Datenstrukturen, welche den assoziativen
Zugriff (über einen bestimmten Wert als Suchkriterium) optimieren
Bäume: Abbildung bzw. Vorberechnung von Entscheidungen
während der Suche in einer geordneten Menge als hierarchische
Datenstruktur (Entscheidungsbaum, Suchbaum)
Hash-Tabellen: Abbildung von Objekten auf den Speicher (deren
Position darin) wird direkt aus dem Suchkriterium als Eigenschaft
der Objekte abgeleitet
Eike Schallehn
Grundlagen der Informatik für Ingenieure
2008/2009
5–34
Grundlegende Datenstrukturen
Bäume, Suchbäume und Hash-Tabellen
Bäume
Grundlegende Datenstruktur zur
Abbildung einer Hierarchie
Setzt Grundprinzip „Teile und
Herrsche“ (siehe Algorithmen (→) als
Datenstruktur um: Zerlegung von
großen Datenmengen in kleinere,
besser handhabbare
Grundstruktur: ausgehend von einer
Wurzel (Gesamtheit) kommt man
über verschiedene Verzweigungen
(Unterteilungen) zu den Blättern
(kleinste Einheiten)
Eike Schallehn
Grundlagen der Informatik für Ingenieure
2008/2009
5–35
Grundlegende Datenstrukturen
Bäume, Suchbäume und Hash-Tabellen
Allgemeine Struktur von Bäumen
Höhe des Baumes
Wurzel
Innere Knoten
1
2
3
4
Blätter
Eike Schallehn
Grundlagen der Informatik für Ingenieure
2008/2009
5–36
Grundlegende Datenstrukturen
Bäume, Suchbäume und Hash-Tabellen
Beispiele: Baumstrukturen in der Informatik
Dateisysteme mit Festplatten, Verzeichnissen, wiederum darin
enthaltenen Verzeichnissen und letztendlich Dateien
Dokumentenstrukturen, z.B. Mit Kapiteln, Abschnitten, Absätzen
◮
HTML und XML als hierarchische Strukturen
Syntaktische Analyse und Auswertung von
Programmen/Termen: Zerlegung eines Satzes einer Sprache
(Grammatik) enstprechend Regeln in Teilausdrücke/Wortgruppen
bis hin zu kleinsten Einheiten (Atome, Terminale)
Suchbäume als Indexe zum schnellen assoziativen Zugriff über
Schlüsselwerte
◮
◮
◮
Datenbanksysteme
Allgemein: Suche nach Worten in Texten
Speziell: Suchmaschinen im World Wide Web
Eike Schallehn
Grundlagen der Informatik für Ingenieure
2008/2009
5–37
Grundlegende Datenstrukturen
Bäume, Suchbäume und Hash-Tabellen
Binäre Suchbäume
12
5
2
17
15
11
14
19
18
21
Binär = Verzweigungsgrad 2: jeder Knoten hat maximal 2
Kindknoten
Jeder Knoten speichert einen Suchschlüssel und repräsentiert
damit folgende Entscheidung:
◮
◮
◮
Ist der gesuchte Wert gleich dem Schlüssel → GEFUNDEN
Ist der Wert kleiner, gehe zum linken Kindknoten
Ist der Wert größer, gehe zum rechten Kindknoten
Eike Schallehn
Grundlagen der Informatik für Ingenieure
2008/2009
5–38
Grundlegende Datenstrukturen
Bäume, Suchbäume und Hash-Tabellen
Binäre Suchbäume: Suchen und Einfügen
Suchen und Einfügen prinzipiell ähnlich:
◮
◮
◮
Algorithmus startet an der Wurzel
In jedem Knoten: wenn Schlüssel nicht gefunden, verzweige zu
einem Kindknoten
Auf Blattebene:
⋆
⋆
Einfügen: neuen Kindknoten erzeugen
Suchen: Worst Case - Schlüssel nicht gefunden
Aufwand für beide Operationen dominiert vom Durchlaufen des
Weges von der Wurzel bis zum Blatt, d.h. Höhe des Baumes an
dieser Stelle
Balancierter Baum (→): Baum ist so gleichmäßig gefüllt, dass
Weg von der Wurzel zu Blättern überall möglichst gleich
Bei balanciertem Baum mit n = 2k Elementen ist die Höhe des
Baumes ca. h = k = log2 n
Durchschnittlicher Aufwand für beide Operationen damit: O(log n)
Eike Schallehn
Grundlagen der Informatik für Ingenieure
2008/2009
5–39
Grundlegende Datenstrukturen
Bäume, Suchbäume und Hash-Tabellen
Balancierte Binäre Suchbäume: Aufwand
Eike Schallehn
Maximale
#Knoten
Höhe
= Aufwand
1= 2^1-1
3=2^2-1
7=2^3-1
15=2^4-1
31=2^5-1
63=2^6-1
127=2^7-1
255=2^8-1
511
1023
...
n
1
2
3
4
5
6
7
8
9
10
...
O(log n)
Grundlagen der Informatik für Ingenieure
2008/2009
5–40
Grundlegende Datenstrukturen
Bäume, Suchbäume und Hash-Tabellen
Binärbaum: Beispielimplementierung (C++)
Einfach Implementierung bestehend aus Klassen für
◮
◮
Knoten mit Schlüssel und Verweisen auf Kindknoten
Binärbaum mit Verweis auf Wurzeln
Implementiert nur Suchen und Einfügen
Eigentliche Daten werden nicht eingetragen, nur Schlüssel vom
Typ int
Hinweise
◮
◮
Verwendet friend-Klassen: umgehen Kapselung, indem
befreundete Klassen auf privat-Daten zugreifen können
Vollständiger Quelltext auf der Web-Seit zur Vorlesung
Eike Schallehn
Grundlagen der Informatik für Ingenieure
2008/2009
5–41
Grundlegende Datenstrukturen
Bäume, Suchbäume und Hash-Tabellen
Binärbaum: Knotenklasse
class Node {
friend class BinaryTree;
private :
int key;
Node* left;
Node* right;
Node(int k) { ... }
bool search(int k);
void insert(int k);
void print(int level);
};
Definiert rekursive Methoden zum Einfügen und Suchen →
Eike Schallehn
Grundlagen der Informatik für Ingenieure
2008/2009
5–42
Grundlegende Datenstrukturen
Bäume, Suchbäume und Hash-Tabellen
Binärbaum: Baumklasse
class BinaryTree {
public :
BinaryTree() {
root = NULL;
}
bool search(int key);
void insert(int key);
void print();
private :
Node* root;
};
Methoden zum Einfügen und Suchen als Einstiespunkt für
Rekursion ausgehend von der Wurzel
Eike Schallehn
Grundlagen der Informatik für Ingenieure
2008/2009
5–43
Grundlegende Datenstrukturen
Bäume, Suchbäume und Hash-Tabellen
Binärbaum: Einfügen
void Node::insert(int k) {
if (k==key) return;
if (k<key)
if (left != NULL) left->insert(k);
else left = new Node(k);
if (k>key)
if (right != NULL) right->insert(k);
else right = new Node(k);
}
Schlüssel vorhanden → Einfügen beenden
Andernfalls, falls möglich im linken (neuer Schlüssel kleiner) oder
rechten Teilbaum einfügen (neuer Schlüssel größer)
Falls kein Kindknoten links oder rechts existiert: neuen Kindknoten
mit neuem Schlüssel erzeugen
Eike Schallehn
Grundlagen der Informatik für Ingenieure
2008/2009
5–44
Grundlegende Datenstrukturen
Bäume, Suchbäume und Hash-Tabellen
Entartung von Bäumen
Balanciertheit wichtige Eigenschaft von Bäumen: garantiert
effiziente Ausführung der Operationen mit O(log n)
Ohne weiteres aber keine garantierte Eigenschaft
Abhängig zum Beispiel von Einfügereihenfolge
Schlechte Einfügereihenfolge kann zu Entartung des Baumes
führen
Im schlimmsten Fall wird Baum zu Liste
Operationen dann mit wesentlich schlechterer Laufzeitkomplexität
O(n): sequentielle Suche
Eike Schallehn
Grundlagen der Informatik für Ingenieure
2008/2009
5–45
Grundlegende Datenstrukturen
Bäume, Suchbäume und Hash-Tabellen
Beispiel: Entartung von Bäumen
1
4
2
2
1
6
3
5
3
4
7
5
6
Balancierter Baum
bei Einfügereihenfolge
4, 2, 6, 3, 1, 7, 5
Eike Schallehn
Entarteter Baum
bei Einfügereihenfolge
1, 2, 3, 4, 5, 6, 7
Grundlagen der Informatik für Ingenieure
2008/2009
7
5–46
Grundlegende Datenstrukturen
Bäume, Suchbäume und Hash-Tabellen
Balancierte Bäume
Sicherstellung einer relativen Ausgeglichenheit bei binären
Bäumen durch spezielle Modifikationsoperationen (Einfügen,
Löschen)
◮
◮
Angabe eines speziellen Balancekriteriums, z.B. AVL-Baum: in
jedem Knoten darf der Höhenunterschied zwischen linkem und
rechten Teilbaum maximal 1 sein!
Wird Balancekriterium verletzt, werden Verfahren zur lokalen
Reorganisation des Baumes angewandt
→ AVL-Bäume, Rot-Schwarz-Bäume
Vollständige Ausgeglichenheit möglich durch Knoten mit
variablem Verzweigungsgrad
◮
◮
◮
Mehr als 1 Schlüssel pro Knoten
Verweis auf Kindknoten mit Werten zwischen 2 Schlüsseln
(Bereich)
Knotengröße kann an Speicherstrukturen angepasst werden (z.B.
Blöcke der Festplatte)
→ B-Bäume
Eike Schallehn
Grundlagen der Informatik für Ingenieure
2008/2009
5–47
Grundlegende Datenstrukturen
Bäume, Suchbäume und Hash-Tabellen
... geht es besser als O(log n)?
Assoziative Zugriffe (Suche über einen Schlüsselwert) mit
Bäumen mit logarithmischem Aufwand O(log n)
D.h. nur ein zusätzlicher Suchschritt notwendige für jede
Verdopplung der Größe der Datenmenge, in der gesucht wird
Geht es noch besser?
Ja, Hash-Tabellen können Schlüsselzugriff (unter bestimmten
Bedingungen) mit konstantem Aufwand O(1) umsetzen
D.h. egal wie groß die Datenmenge, das Finden der richtigen
Daten geht immer gleich schnell!
Eike Schallehn
Grundlagen der Informatik für Ingenieure
2008/2009
5–48
Grundlegende Datenstrukturen
Bäume, Suchbäume und Hash-Tabellen
Hash-Tabellen
Auch Streuwerttabelle oder Hash Map
Grundprinzip: Berechnung der Position der Daten im Speicher
(strukturiert als Tabelle) aus dem Schlüsselwert key
◮
◮
Berechnung der Position beim Einfügen
Berechnung der Position beim Suchen
Erfordert Vorreservierung eines Speicherbereichs der Größe M →
M meist sehr groß, ab mehreren Tausend Einträgen
Positionen 0 . . . M − 1 in Speicherbereich werden auch Hash
Buckets genannte
Berechnung der Position über spezielle Hash-Funktion
h : dom(key) → {0, 1, . . . , M − 1}
Wahlfreier Zugriff im RAM und auf Festplatte ermöglicht direkten
Zugriff auf an dieser Stelle gespeicherte Daten
Eike Schallehn
Grundlagen der Informatik für Ingenieure
2008/2009
5–49
Grundlegende Datenstrukturen
Bäume, Suchbäume und Hash-Tabellen
Einfügen in Hash-Tabellen
Zu speichernde
Objekte
Hash-Tabelle
Student Udo Urban
MatrNr 170481
0
1
2
Student Eva Lange
MatrNr 175783
156324, Max Müller
170481, Udo Urban
3
4
Student Max Müller
MatrNr 156324
5
6
175783, Eva Lange
Hash-Funktion
h(MatrNr)=MatrNr % 7
Eike Schallehn
Grundlagen der Informatik für Ingenieure
2008/2009
5–50
Grundlegende Datenstrukturen
Bäume, Suchbäume und Hash-Tabellen
Suchen in Hash-Tabellen
Hash-Tabelle
0
Suche nach
Matrikelnummer:
1
170481
3
2
156324, Max Müller
170481, Udo Urban
4
5
6
175783, Eva Lange
Hash-Funktion
h(MatrNr)=MatrNr % 7
Eike Schallehn
Grundlagen der Informatik für Ingenieure
2008/2009
5–51
Grundlegende Datenstrukturen
Bäume, Suchbäume und Hash-Tabellen
Hash-Funktionen
Wertebereich ist (beim hier betrachteten statischen Hashen)
durch Speichergröße M bestimmt
Problem: Hash-Funktion ist nicht injektiv, d.h. verschiedene
Schlüssel können auf eine Adresse abgebildet werden →
Kollisionen!
Gute Hash-Funktionen erzeugen möglichst zufällig gestreute
Speicherzuordnung und machen dadurch Kollisionen
unwahrscheinlich
Meist umgesetzt durch
◮
◮
◮
Kombination von verschiedenen Operationen mit möglichst
zufälligem Ergebnis, z.B. Bit-Verschiebeoperationen
Am Ende Modulodivision durch M → Rest ist Hash-Wert
Primzahlen als Parameter der Hash-Funktion sorgen für gute,
zufällige Verteilung
Kollisionen lassen sich aber meist nicht völlig vermeiden →
erfordern Kollisionsbehandlung
Eike Schallehn
Grundlagen der Informatik für Ingenieure
2008/2009
5–52
Grundlegende Datenstrukturen
Bäume, Suchbäume und Hash-Tabellen
Hash-Tabellen: Kollisionsbehandlung
Verkettete Liste: der Eintrag in einer Hash-Tabelle verweist auf eine
Liste der dorthin gehashten Daten
Kann bei schlechter Hash-Funktion mit vielen
Kollisionen zu Entartung führen
Mehraufwand für Speicherung
Sondieren: (engl. Probing) ist der Hash Bucket bereits belegt, wird
nach einem einfachen Muster ein anderer Platz gesucht
Z.B. lineares Sondieren: testen ob folgende Hash
Bucket frei ist, erster freier wird genutzt
Doppeltes Hashen: ist der Hash Bucket belegt, wird (ggf. wiederholt)
ein weiterer Hash-Wert berechnet und diese Position
getestet
Eike Schallehn
Grundlagen der Informatik für Ingenieure
2008/2009
5–53
Grundlegende Datenstrukturen
Bäume, Suchbäume und Hash-Tabellen
Implementierung von Hash-Tabellen
(Bisher besprochene) statische Hash-Verfahren: vordefinierte
Speichergröße kann effizient über Array umgesetzt werden
Dynamische Hash-Verfahren können den benutzten
Speicherbereich zur Laufzeit Vergrößern → z.B. durch verkettete
Arrays
Kollisionsbehandlung durch verkettet Liste erfordert zusätzliche
Datenstruktur
Sondieren und Doppeltes Hashen Erfordern aufwändigere
Operationsimplementierungen
Beispielimplementierung auf der Web-Seite zur Vorlesung
◮
◮
Einfaches statisches Hashverfahren mit linearem Sondieren
In der Vorlesung nicht vorgestellt
Eike Schallehn
Grundlagen der Informatik für Ingenieure
2008/2009
5–54
Grundlegende Datenstrukturen
Bäume, Suchbäume und Hash-Tabellen
Nachteile von Hashtabellen
Keine Ordnung der Elemente: in Bäumen sind Elemente stets
geordnet gespeichert – geordnete Ausgabe aus einer Hash-Tabelle
erfordert zusätzliche Sortierung
Vorreservierung des Speichers notwendig: z.B. über Arrays, die zur
Vermeidung von Überlauf und Kollisionen ggf. weit überdimensioniert
sind (Trade-off: Speichereffizienz vs. Laufzeiteffizienz)
Überlauf möglich: bei einigen statischen Verfahren (z.B. bei
Überlaufbehandlung durch Sondieren, nicht bei verketteter Liste) kann
die Hash-Tabelle tatsächlich vollständig gefüllt werden, so dass keine
weiteren Daten eingetragen werden können
Aufwand für Dynamik: Verfahren, welche zur Vermeidung von
Überläufen und Kollisionen, die Hash-Tabelle dynamisch wachsen
lassen, nähern sich mit ihrem Laufzeitverhalten Bäumen an
Aufwand für Überlaufbehandlung: auch bei vielen Kollisionen, z.B.
durch schlechte Hash-Funktion, verschlechtert sich die
Laufzeitkomplexität
Eike Schallehn
Grundlagen der Informatik für Ingenieure
2008/2009
5–55
Grundlegende Datenstrukturen
Bäume, Suchbäume und Hash-Tabellen
Zusammenfassung: Datenstrukturen
Klassische Datenstrukturen bieten Standardlösungen für effiziente
Bearbeitung von Daten
Wichtigste hier vorgestellt:
◮
◮
◮
Kollektionsdatentypen wie Listen, Mengen und Multimengen zur
Verwaltung einer Sammlung zusammengehörender Objekte
Queues und Stacks zur Steuerung der Berabeitungsreihenfolge
von Datenobjekten
Bäume und Hash-Tabellen für schnelles Suchen von Daten über
einen Schlüsselwert
Oft in Form von generischen Klassenbibliotheken umgesetzt, z.B.
STL in C++
Eigene Implementierung durch Verwendung von Typkonstruktoren
(Arrays, Structs, Klassen) und Zeiger sowie Klassenschablonen
(Templates, Generics) möglich
Eike Schallehn
Grundlagen der Informatik für Ingenieure
2008/2009
5–56
Herunterladen