19
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

Einführung in die Informatik für Naturwissenschaftler und Ingenieure

  • 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

Page 1: Einführung in die Informatik für Naturwissenschaftler und Ingenieure

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

Page 2: Einführung in die Informatik für Naturwissenschaftler und Ingenieure

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)

Page 3: Einführung in die Informatik für Naturwissenschaftler und Ingenieure

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, … ;

Page 4: Einführung in die Informatik für Naturwissenschaftler und Ingenieure

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)

Page 5: Einführung in die Informatik für Naturwissenschaftler und Ingenieure

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!

Page 6: Einführung in die Informatik für Naturwissenschaftler und Ingenieure

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

Page 7: Einführung in die Informatik für Naturwissenschaftler und Ingenieure

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

Page 8: Einführung in die Informatik für Naturwissenschaftler und Ingenieure

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(¢)

Page 9: Einführung in die Informatik für Naturwissenschaftler und Ingenieure

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!

Page 10: Einführung in die Informatik für Naturwissenschaftler und Ingenieure

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

Page 11: Einführung in die Informatik für Naturwissenschaftler und Ingenieure

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!

Page 12: Einführung in die Informatik für Naturwissenschaftler und Ingenieure

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:

Page 13: Einführung in die Informatik für Naturwissenschaftler und Ingenieure

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:

Page 14: Einführung in die Informatik für Naturwissenschaftler und Ingenieure

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

Page 15: Einführung in die Informatik für Naturwissenschaftler und Ingenieure

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.

Page 16: Einführung in die Informatik für Naturwissenschaftler und Ingenieure

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

Page 17: Einführung in die Informatik für Naturwissenschaftler und Ingenieure

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

Page 18: Einführung in die Informatik für Naturwissenschaftler und Ingenieure

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

Page 19: Einführung in die Informatik für Naturwissenschaftler und Ingenieure

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