Upload
talen
View
13
Download
0
Embed Size (px)
DESCRIPTION
Wintersemester 2005/06. Einführung in die Informatik für Naturwissenschaftler und Ingenieure ( alias Einführung in die Programmierung) (Vorlesung). Prof. Dr. Günter Rudolph Fachbereich Informatik Lehrstuhl für Algorithm Engineering. Kapitel 14: Exkurs Hashing. Inhalt Motivation - PowerPoint PPT Presentation
Citation preview
Einführung in die Informatik für
Naturwissenschaftler und Ingenieure
(alias Einführung in die Programmierung)
(Vorlesung)
Prof. Dr. Günter Rudolph
Fachbereich Informatik
Lehrstuhl für Algorithm Engineering
Wintersemester 2005/06
Rudolph: EINI (WS 2005/06) ● Kap. 14: Exkurs Hashing 2
Kapitel 14: Exkurs Hashing
Inhalt
● Motivation
● Grobentwurf
● ADT List
● ADT HashTable
● Anwendung
● Umstrukturierung des Codes (refactoring)
Rudolph: EINI (WS 2005/06) ● Kap. 14: Exkurs Hashing 3
Kapitel 14: Exkurs Hashing
Motivation
Gesucht: Datenstruktur zum Einfügen, Löschen und Auffinden von Elementen
Binäre Suchbäume!
Problem: Binäre Suchbäume erfordern eine totale Ordnung auf den Elementen
Totale Ordnung
Jedes Element kann mit jedem anderen verglichen werden:
Entweder a < b oder a > b oder a = b. Beispiele: N, R, { A, B, …, Z }, …
Partielle Ordnung
Es existieren unvergleichbare Elemente: a || b
Beispiele: N2, R3, … ;
Rudolph: EINI (WS 2005/06) ● Kap. 14: Exkurs Hashing 4
Kapitel 14: Exkurs Hashing
Motivation
Gesucht: Datenstruktur zum Einfügen, Löschen und Auffinden von Elementen
Problem: Totale Ordnung nicht auf natürliche Art vorhanden
Beispiel: Vergleich von Bilddaten, Musikdaten, komplexen Datensätzen
Alternative Suchverfahren notwendig! Hashing
Lineare Liste!
Funktioniert, jedoch mit ungünstiger Laufzeit:
1. Feststellen, dass Element nicht vorhanden: N Vergleiche auf Gleichheit
2. Vorhandenes Element auffinden: im Mittel (N+1) / 2 Vergleiche(bei diskreter Gleichverteilung)
Rudolph: EINI (WS 2005/06) ● Kap. 14: Exkurs Hashing 5
Kapitel 14: Exkurs Hashing
Idee
1. Jedes Element e bekommt einen numerischen „Stempel“ h(e), der sich aus dem Dateninhalt von e berechnet
2. Aufteilen der Menge von N Elementen in M disjunkte Teilmengen,wobei M die Anzahl der möglichen Stempel ist→ Elemente mit gleichem Stempel kommen in dieselbe Teilmenge
3. Suchen nach Element e nur noch in Teilmenge für Stempel h(e)
Laufzeit (Annahme: alle M Teilmengen ungefähr gleich groß)
a) Feststellen, dass Element nicht vorhanden: N / M Vergleiche auf Gleichheit
b) Vorhandenes Element auffinden: im Mittel (N / M +1) / 2 Vergleiche(bei diskreter Gleichverteilung)
deutliche Beschleunigung!
Rudolph: EINI (WS 2005/06) ● Kap. 14: Exkurs Hashing 6
Kapitel 14: Exkurs Hashing
Grobentwurf
1. Jedes Element e E bekommt einen numerischen „Stempel“ h(e), der sich aus dem Dateninhalt von e berechnet
2. Elemente mit gleichem Stempel kommen in dieselbe Teilmenge
3. Suchen nach Element e nur noch in Teilmenge für Stempel h(e)
Funktion h: E → { 0, 1, …, M – 1 } heißt Hash-Funktion (to hash: zerhacken)
Anforderung: sie soll zwischen 0 und M – 1 gleichmäßig verteilen
M Teilmengen werden durch M lineare Listen realisiert (ADT List)
Tabelle der Größe M enthält für jeden Hash-Wert einen Zeiger auf seine Liste
Suche nach e → Berechne h(e), hole Zeiger auf Liste aus Tabelle[ h(e) ],
Suche in dieser Liste nach Element e
Rudolph: EINI (WS 2005/06) ● Kap. 14: Exkurs Hashing 7
Kapitel 14: Exkurs Hashing
Grobentwurf
Weitere Operationen auf der Basis von „Suchen“
● Einfügen von Element e
→ Suche nach e in Liste für Hash-Werte h(e) Nur wenn e nicht in dieser Liste, dann am Anfang der Liste einfügen
● Löschen von Element e
→ Suche nach e in Liste für Hash-Werte h(e) Wenn e in der Liste gefunden wird, dann aus der Liste entfernen
Auch denkbar: Ausnahme werfen, falls
einzufügendes Element schon existiert oder zu löschendes Element nicht vorhanden
Rudolph: EINI (WS 2005/06) ● Kap. 14: Exkurs Hashing 8
Kapitel 14: Exkurs Hashing
Grobentwurf
0
1
2
3
…
M-1
M Listen
Tabelle der Größe M mit M Listenzeigern
N Elemente aufgeteilt in M Listen gemäß ihres Hash-Wertes h(¢)
Rudolph: EINI (WS 2005/06) ● Kap. 14: Exkurs Hashing 9
Kapitel 14: Exkurs Hashing
Was ist zu tun?
1. Wähle Datentyp für die Nutzinformation eines Elements
hier: integer (damit der Blick frei für das Wesentliche bleibt)
2. Realisiere den ADT IntList zur Verarbeitung der Teilmengen
Listen kennen und haben wir schon in C; jetzt aber als C++ Klasse!
3. Realisiere den ADT HashTable
Verwende dazu den ADT IntList und eine Hash-Funktion
4. Konstruiere eine Hash-Funktion h: E → { 0,1, …, M – 1}
Kritisch! Wg. Annahme, dass h(¢) gleichmäßig über Teilmengen verteilt!
Rudolph: EINI (WS 2005/06) ● Kap. 14: Exkurs Hashing 10
Kapitel 14: Exkurs Hashing
ADT IntList
class IntList {private: int elem; IntList *head; IntList *next;
bool Contains(IntList *aList, int aElem); IntList *Delete(IntList *aList, int aElem); void Delete(IntList *aList); void Print(IntList *aList);
public: IntList(); IntList(int aElem);
void Insert(int aElem); bool Contains(int aElem); void Delete(int aElem); void Print();
~IntList();};
private rekursive Funktionen
öffentliche Methoden,
z.T. überladen
Rudolph: EINI (WS 2005/06) ● Kap. 14: Exkurs Hashing 11
Kapitel 14: Exkurs Hashing
ADT IntList
IntList::IntList() : head(0), next(0), elem(0) {}
IntList::IntList(int aElem) : head(0), next(0), elem(aElem) {}
IntList::~IntList() { Delete(head);}
void IntList::Delete(IntList *aList) { if (aList == 0) return; Delete(aList->next); delete aList;}
Konstruktoren
Destruktor
private Hilfsfunktion des Destruktors:
löscht Liste rekursiv!
Rudolph: EINI (WS 2005/06) ● Kap. 14: Exkurs Hashing 12
Kapitel 14: Exkurs Hashing
ADT IntList
bool IntList::Contains(IntList *aList, int aElem) { if (aList == 0) return false; if (aList->elem == aElem) return true; return Contains(aList->next, aElem);}
bool IntList::Contains(int aElem) { return Contains(head, aElem); }
öffentliche Methode:
private überladene Methode:
Rudolph: EINI (WS 2005/06) ● Kap. 14: Exkurs Hashing 13
Kapitel 14: Exkurs Hashing
void IntList::Delete(int aElem) { head = Delete(head, aElem); }
IntList *IntList::Delete(IntList *aList, int aElem) { if (aList == 0) return 0; if (aList->elem == aElem) { IntList *tmp = aList->next; // Zeiger retten delete aList; // Objekt löschen return tmp; // Zeiger zurückgeben } aList->next = Delete(aList->next, aElem); return aList;}
ADT IntList
öffentliche Methode:
private überladene Methode:
Rudolph: EINI (WS 2005/06) ● Kap. 14: Exkurs Hashing 14
Kapitel 14: Exkurs Hashing
void IntList::Print() { Print(head); }
void IntList::Print(IntList *aList) { static int cnt = 1; // counter if (aList != 0) { cout << aList->elem; cout << (cnt++ % 6 ? "\t" : "\n"); Print(aList->next); } else { cnt = 1; cout << "(end of list)" << endl; }}
ADT IntList
öffentliche Methode:
private überladene Methode:Speicherklasse static :Speicher wird nur einmal angelegt
Rudolph: EINI (WS 2005/06) ● Kap. 14: Exkurs Hashing 15
Kapitel 14: Exkurs Hashing
void IntList::Insert(int aElem) { if (Contains(aElem)) return; IntList *newList = new IntList(aElem); newList->next = head; head = newList;}
ADT IntList
öffentliche Methode:
→ Implementierung von ADT IntList abgeschlossen.
Rudolph: EINI (WS 2005/06) ● Kap. 14: Exkurs Hashing 16
Kapitel 14: Exkurs Hashing
ADT HashTable
class HashTable {private: IntList **table; int maxBucket;public: HashTable(int aMaxBucket); int Hash(int aElem) { return aElem % maxBucket; }
bool Contains(int aElem) { return table[Hash(aElem)]->Contains(aElem); }
void Delete(int aElem) { return table[Hash(aElem)]->Delete(aElem); }
void Insert(int aElem) { return table[Hash(aElem)]->Insert(aElem); }
void Print(); ~HashTable();};
Rudolph: EINI (WS 2005/06) ● Kap. 14: Exkurs Hashing 17
Kapitel 14: Exkurs Hashing
ADT HashTable
HashTable::HashTable(int aMaxBucket) : maxBucket(aMaxBucket) { if (maxBucket < 2) throw "invalid bucket size"; table = new IntList* [maxBucket]; for (int i = 0; i < maxBucket; i++) table[i] = new IntList();}
HashTable::~HashTable() { for (int i = 0; i < maxBucket; i++) delete table[i]; delete table;}
void HashTable::Print() { for (int i = 0; i < maxBucket; i++) { cout << "\nBucket " << i << " :\n"; table[i]->Print(); }}
Rudolph: EINI (WS 2005/06) ● Kap. 14: Exkurs Hashing 18
Kapitel 14: Exkurs Hashing
ADT HashTable
int main() { int maxBucket = 17; HashTable *ht = new HashTable(maxBucket); for (int i = 0; i < 2000; i++) ht->Insert(rand());
int hits = 0; for (int i = 0; i < 2000; i++) if (ht->Contains(rand())) hits++;
cout << "Treffer: " << hits << endl;}
unsigned int Pseudozufallszahlen
Ausgabe: Treffer: 137
Rudolph: EINI (WS 2005/06) ● Kap. 14: Exkurs Hashing 19
Kapitel 14: Exkurs Hashing
ADT HashTable: Verteilung von 2000 Zahlen auf M Buckets
0
20
40
60
80
100
120
140
160
180
0 2 4 6 8 10 12 14 16 18
M = 13
M = 17
M = 19
MMittel-wert
Std.-Abw.
13 149 13,8
17 114 8,1
19 102 6,7
Hash-Funktion ist wohl OK