7 Sortieren und Suchen nach dem Hash

Werbung
Programmieren 1
Prof. Dr.-Ing. Silvia Keller
Studiengang Angewandte Informatik
Ausgabe: 19.03.2004
Seite 104 von 110
7 Sortieren und Suchen nach dem Hash-Verfahren
D
AS
PR
OBLEM
Gegeben ist eine Liste von Namen. Diese Namen sind mit einem Verfahren so zu
sortieren, dass ein Name k mit dem gleichen Verfahren gesucht werden kann
D
IE
7.1
ID
EE
:
SORTIEREN MIT HASH-FUNKTIONEN
Man speichert die Namen in einer Liste mit M Elementen, also ein array, in dem M Werte Platz finden.
Liste mit M Werten
0
Name k
HashFunktion
Position i
M-1
Die Position eines zu sortierenden Namen k in der Liste berechnet man über eine Funktion, HashFunktion genannt.
Der in der Liste einzutragenden Name k ist Eingabeparameter der Hashfunktion H. Als Ergebnis liefert
die Hash-Funktion die Position i im array, in der der Name zu speichern ist. Die gleiche Funktion H wird
benutzt, um die Position eines gesuchten Namen f in der Liste zu bestimmen. Der gesuchte Name f ist
dann ebenfalls Eingabeparameter der Hash-Funktion H. Ergebnis von H ist die Position in der Liste, an
der der gesuchte Name f steht.
Beispiel:
Die Liste enthält 10 Datenelemente, also ist
M=10.
Zu sortieren sind die Namen:
Keller, Hulin, Ertel, Gampp
Hash-Funktion H(k)
ist die Ordnungsnummer des ersten Buchstabens
des Namen k modulo M
Î
Die Hash-Funktion muss immer einen Wert mit
dem Modulo-Operator berechnen, damit die
berechnete Position i immer innerhalb des array
liegt.
Zum Einfügen der Namen in die richtige Position wird die Hash-Funktion H(k) wie folgt auf die sortierende
Namen angewendet:
Programmieren 1
Prof. Dr.-Ing. Silvia Keller
Studiengang Angewandte Informatik
Ausgabe: 19.03.2004
Seite 105 von 110
Liste mit 10 Werten
0
Gampp
H(Keller)= 75 modulo 10 = 5
H(Hulin) = 72 modulo 10 = 2
Hulin
H(Ertel) = 69 modulo 10 = 9
H(Gampp) = 71 modulo 10 = 1
Keller
9
7.2
Ertel
SUCHEN
Bei der Suche nach einem Namen wird ebenfalls die Hash-Funktion verwendet. Ein Suche nach dem
Namen Gampp ergibt:
H(Gampp) = 71 modulo 10 = 1
An dieser Position steht tatsächlich auch der Name Gampp.
Eine Suche nach dem Namen „Brümmer“ ergibt:
H(Brümmer) = 66 modulo 10 = 6
An dieser Position ist kein Name gespeichert
Ein Vergleich des gesuchten Namens „Brümmer“ mit dem Eintrag in der Liste ergibt jedoch – die Position
ist leer. Der Name „Brümmer“ wurde nicht in die Liste eingetragen.
7.3
KOLLISSIONEN
Es soll ein weiterer Name „Koch“ in die Liste eingetragen werden.
Die Berechnung der Hash-Funktion ergibt:
H(Koch) = 75 modulo 10 = 5
An Position 5 ist jedoch schon der Name „Keller“ eingetragen. Die Berechnung des Namens „Koch“ führte
zu einer Kollission.
Wie kann dieses Problem gelöst werden ?
Idee
Zur Lösung der Kollission wird versucht für den Namen „Koch“ eine Ausweichposition zu bestimmen.
Wenn also Position 5 schon mit dem Namen „Keller“ belegt ist, dann versuchen wir den Namen an die
folgende Position, also 6, zu schreiben. In unserem Fall ist die Position 6 frei und damit eine Lösung des
Problems. „Koch“ wird also an die Position H(Koch ) + 1 eingetragen.
Wäre diese Position jedoch auch belegt, versucht man die nächste folgende Position also H(Koch ) + 2
usw.
Programmieren 1
Prof. Dr.-Ing. Silvia Keller
Studiengang Angewandte Informatik
Ausgabe: 19.03.2004
Seite 106 von 110
Diese Strategie eine Ausweichposition zu finden wird solange angewendet bis entweder ein freier Platz
zur Speicherung des Namens gefunden ist oder aber die Liste vollständig ohne Resultat nach freien
Positionen durchsucht wurde.
Zur Lösung der Kollission wird also eine weitere Funktion angewendet, Kollossions-Funktion genannt.
Die oben beschriebene Strategie für die Kollssionsbehandlung wird lineares Sondieren genannt und
versucht ausgehend von der berechneten Hash-Position H(Koch ) alle folgenden Positionen in der Liste:
(H(k) + i ) modulo M
1 <= i < M
Bei der Suche nach dem Namen „Koch“ liefert die Hash-Funktion die Position 5. Da bei jeder durch die
Hash-Funktion errechneten Position eine Kollission möglich war, muss ein Vergleich des gesuchten
Namens mit dem Namen an der errechneten Position erfolgen. Steht der gesuchte Namen nicht an der
errechneten Position, wurde der gesuchte Name, wenn dieser überhaupt in der Liste vorkommt, über
eine Kollissionsbehandlung an eine Ausweichposition geschrieben. Also muss auch beim Suchen alle
Ausweichpositionen nach dem Namen durchsucht werden. Die Suche endet dann, wenn entweder der
gesuchte Name, hier „Koch“, in der Liste gefunden werden konnte, oder aber die errechnete Position frei
ist. Im letzten Fall kommt der gesuchte Name nicht in der Liste vor.
Im konkreten Beispiel wird zuerst an der errechneten Hash-Position 5 nach Koch gesucht, dann die
Ausweichposition 6 berechnet. Hier endte die Suche, da der Eintrag Koch gefunden wurde.
7.4 LÖSCHEN
Im obigen Beispiel soll nach Einfügen von „Koch“ der Name „Keller“ aus der Liste gelöscht werden. Die
Liste würde nach einem Löschvorgang folgendes Aussehen haben:
Liste mit 10 Werten
0
Gampp
Hulin
Koch
9
Die Position 5 ist nach dem Löschen frei. Wollen wir jetzt nach dem
Namen „Koch“ suchen berechnet die Hash-Funktion die Position 5. An der
Position 5 steht kein Name mehr, also endet hier die Suche mit dem
Ergebnis: Der Name „Koch“ kommt in der Liste nicht vor. Dies ist
aber nicht richtig, da Koch an der Position 6 steht.
Ertel
Das Problem
besteht darin, dass Koch vorher über eine Kollission in die Liste eingetragen wurde. Nach dem Löschen
von Keller tritt keine Kollssion mehr auf.
Wie kann man dieses Problem lösen ?
In der Liste wird eine gelöschte Position durch den Eintrag „Hier wurde was gelöscht“ gekennzeichnet.
Nach der Berechnung der Hash-Funktion
H(Koch) = 5
findet man den Eintrag „ Hier wurde was gelöscht“, d.h. „Koch“ könnte durch eine Kollission an einer
anderen Position stehen. Also muss die Kollissionsbehandlung angewendet werden. Entweder man
findet über die Kollissionsbehandlung den Namen „Koch“ ( in diesem Beispiel an der Position 6 ) oder
aber man trifft auf eine freie Position. Im ersten Fall ist „Koch“ gefunden im zweiten Fall kommt der Name
„Koch“ in der Liste tatsächlich nicht vor.
Programmieren 1
7.5
Prof. Dr.-Ing. Silvia Keller
Studiengang Angewandte Informatik
Ausgabe: 19.03.2004
Seite 107 von 110
EIGENSCHAFTEN EINER HASH-FUNKTION
Das Hashverfahren arbeitet sehr schnell , wenn
1. Die Hash-Funktion sehr einfach zu berechnen ist
2. als Ergebnis der Hash-Funktion alle möglichen Positionen von 0 bis M-1 in der Liste möglich
sind, d.h. die Hash-Funktion ist surjektiv
3. die Hash-Funktion die Dateneelemente in der Liste gut streut
4. möglichst wenig Kollssionen auftreten
7.5.1
Beispiel für übliche Hash-Funktionen
Die zu sortierenden Werte werden im Folgenden als Schlüssel bezeichnet. Ein Schlüssel kann entweder
eine Zahl oder eine Zeichenfolge sein.
8
Sortiert werden soll eine Zeichenkette mit Anzahl k Zeichen z.B. es sollen Namen sortiert werden
k
H ( Schlüssel ) = ∑ Ordnungszahl ( Zeicheni ) modulo M
i =1
8
Es sollen natürliche Zahlen sortiert werden ( Divisionsmethode )
H(Schlüssel) = Zahl modulo M
8
Es sollen natürliche Zahlen sortiert werden. Die Zahlen werden als Folge von Ziffern znzn-1...z1
interpretiert ( Mittel-Quadrat-Methode )
H ( Schlüssel ) berechnet sich wie folgt:
•
•
7.5.2
Bilde das Quadrat der Zahl. Der berechnete Wert ist neue Ziffernfolge mit einer Anzahl von
Ziffern grösser oder gleich n
Entnehme den mitteleren Block von n Ziffern. Diese Ziffern ergeben die Position in der Liste.
Beispiele für Kollissions-Funktionen
Die zu sortierenden Werte werden im Folgenden als Schlüssel bezeichnet. Ein Schlüssel kann entweder
eine Zahl oder eine Zeichenfolge sein.
Lineares Sondieren
Ausweichposi( Schlüssel ) = ( H(Schlüssel) + i ) modulo M,
1 <= i <= M-1
Quadratisches Sondieren
Ausweichposi(Schlüssel ) = ( H(Schlüssel ) +(-) i 2 ) modulo M,
1 <= i <= M-1
Herunterladen