Elementare Suchmethoden

Werbung
Elementare Suchmethoden
Unter Suchen wird das Wiederauffinden von Information aus einer großen Menge zuvor gespeicherter
Informationen verstanden. Normalerweise wird Information in Datensätzen gespeichert, die einen Schlüssel
besitzen, nach dem gesucht wird. Das Ziel ist es, alle Elemente aufzufinden, deren Schlüssel mit dem
Suchschlüssel übereinstimmt.
Das Suchen benötigt bestimmte Datenstrukturen, diese kann man einfach mittels Wörterbüchern erklären. Im
Wörterbuch sind die Wörter die Schlüssel, und die Lautschrift, die Definitionen usw. die dazu gespeicherten
Informationen.
Zur Datenstruktur gehört es aber auch, wie mit gleichen Schlüsseln umgegangen wird. Die erste Möglichkeit
ist, in der Primärstruktur keine doppelten Schlüssel zuzulassen. Es ist dann aber notwendig, daß jeder
Datensatz in der Primärstruktur eine Verkettung zu einer Liste mit den Datensätzen hat, die diesen Schlüssel
haben. In der Primärstruktur könnten aber auch gleiche Schlüssel zugelassen werden. Es muß dann aber
gewährleistet sein, alle Daten wieder aufgefunden werden können. Die letzte Möglichkeit besteht auf ein
eindeutiges Kennzeichen jedes Datensatzes.
1 Sequentielle Suche
14
8
17
30
12
16
31
29
4
20
19
12
Die Daten werden in einem Feld gespeichert, und neue Datensätze am Ende angefügt. Beim Suchen wird jedes
Element des Feldes nach dem anderen durchsucht, bis die Suche erfolgreich war, oder das Ende des Feldes
erreicht wird.
Die sequentielle Suche in einem unsortierten Feld benötigt N+1 Vergleiche für eine erfolglose Suche, und
durchschnittlich ungefähr N/2 Vergleiche für eine erfolgreiche Suche.
Verwendet man ein sortiertes Feld, so kann die Suche als erfolglos abgebrochen werden, wenn ein Schlüssel
gefunden wird, der größer als der gesuchte Schlüssel ist.
Die sequentielle Suche in einem sortierten Feld benötigt sowohl für eine erfolgreiche aber auch für die
erfolglose Suche ungefähr N/2 Vergleiche.
4
8
12
15
16
17
19
20
29
30
31
18
Um die Suche zu beschleunigen kann man die am häufigsten benötigten Datensätze an den Beginn des Feldes
stellen. Ist keine Information über die Häufigkeit vorhanden, kann man den zuletzt gesuchten Datensatz an den
Beginn des Feldes stellen. Dies ist dann besonders effizient, wenn die meisten Zugriffe auf einen Datensatz
eng aufeinander folgen.
2 Binäre Suche (binary search)
Die Suchzeit kann gegenüber der sequentiellen Suche verringert werden, indem man ein sortiertes Feld
durchsucht. Das Feld wird in zwei Hälften geteilt, und festgestellt in welcher Hälfte des Feldes sich der
gesuchte Datensatz befindet. Diese Methode wird dann rekursiv angewandt, bis nur mehr ein Datensatz übrig
1
ist. Dieser kann der gesuchte sein, oder den Datensatz mit dem gesuchten Schlüssel gibt es nicht. Im Beispiel
wird nach der Zahl 13 gesucht:
2
1
1
1
3
5
5
5
7
8
9
12 13 14 16 18 19 24
9
12 13 14 16 18 19 24
9
12 13
13
Binäre Suche erfordert sowohl für erfolgreiche als auch für erfolglose Suche niemals mehr als lg(N+1)
Vergleiche.
Dies gilt, weil bei jedem Schritt die Anzahl der Datensätze halbiert wird. Ein Problem entsteht bei nicht
eindeutigen Schlüsseln. Wenn während der Suche ein gesuchter Datensatz gefunden wird, müssen dann
nämlich auch dessen Nachbarn durchsucht werden.
Die Folge der Vergleiche ist beim binären Suchen vorbestimmt, und kann in einem binären Baum dargestellt
werden. Später werden noch Algorithmen beschrieben, die speziell konstruierte Baumstrukturen zur Steuerung
der Suche benötigen.
8
3
14
1
1
5
1
5
12
5
9
18
13
7
16
19
24
2.1 Interpolationssuche (interpolation search)
Diese stellt eine mögliche Verbesserung dar. Hier versucht man genauer zu erraten, wo sich das gesuchte
Element befindet. Dies erinnert an die Suche in einem Telefonbuch, wo man eher vorne zu suchen beginnt,
wenn der gesuchte Name mit einem B beginnt. Im Beispiel wird wieder nach der 13 gesucht:
1
1
1
3
5
5
5
7
8
9
12 13 14 16 18 19 24
9
12 13 14 16 18 19 24
13 14 16 18 19 24
Interpolationssuche erfordert für erfolgreiche aber auch für erfolglose Suche niemals mehr als lg[lg(N+1)]
Vergleiche.
Die Interpolationssuche ist besonders für große, gleichmäßig verteilte Felder geeignet, da z. B. für eine
Milliarde Elemente nur maximal 5 Schritte erforderlich wären. Ein Nachteil ist, das die Interpolationssuche bei
einer sehr ungleichmäßigen Verteilung hereingelegt werden kann. Bei kleinen Feldern ist auch der Vorteil der
durch die Interpolation entsteht sehr gering.
3 Suche in einem Binärbaum (binary tree search)
Wie bereits bekannt ist, kann man die Folge der Vergleiche des binären Suchens in einem binären Baum
darstellen. Die Idee ist nun, die Daten in einem Baum durch Verkettung zu speichern. Der Vorteil gegenüber
3
der binären Suche ist, daß die Datenstruktur immer leicht wartbar ist. Es ist einfach ein neues Element
einzubinden und ohne kompliziertes Herumschieben von Daten ist immer eine sortierte Struktur vorhanden.
Sie ist eine der fundamentalsten Methoden der Informatik. Trotz ihrer Einfachheit ist sie effizient, und wird
daher sehr oft eingesetzt.
4
Ein Baum ist dadurch definiert, daß jedes Glied genau ein übergeordnetes hat. Ein binärer Baum hat zusätzlich
noch die Eigenschaft, daß jeder Knoten eine linke und eine rechte Verkettung hat. Beim binären Suchen wird
weiters davon ausgegangen, daß alle Datensätze mit einem kleineren Schlüssel im linken Unterbaum und alle
größeren und gleichen im rechten Unterbaum sind.
Bei der Suche vergleicht man den gesuchten Schlüssel mit der Wurzel, und geht dann in den entsprechenden
Unterbaum, wo diese Vergleiche rekursiv fortgesetzt werden, bis die Gleichheit der Schlüssel erreicht ist, oder
wenn der entsprechende Unterbaum leer ist.
A
S
E
A
R
C
H
Um einen Knoten hinzuzufügen, verfährt man wie beim erfolglosen Suchen, nur wird dann der leere
Unterbaum durch den einzufügenden Knoten (I) ersetzt.
A
S
E
A
R
C
H
I
Ein Suchen oder Einfügen in einem binären Suchbaum erfordert durchschnittlich ca. 2 ln N Vergleiche, wenn
der Baum aus N zufälligen Schlüsseln aufgebaut ist.
Die Laufzeit von Algorithmen, die binäre Suchbäume betreffen sind stark von der Form der Bäume abhängig.
Bei ausgeglichenen Bäumen kann sie sogar logarithmisch werden. Durch die Art des Aufbauens der Bäume
können aber auch extrem ungünstige Bäume entstehen (A Z B Y C X ... oder A B C D E F ...).
Im ungünstigsten Fall kann eine Suche in einem binären Suchbaum mit N Schlüsseln N Vergleiche erfordern.
4 Löschen
Die bis jetzt behandelten Algorithmen waren recht unkompliziert im Vergleich zum Löschen einzelner
Elemente aus einem binären Suchbaum. Hier kommt es nämlich darauf an, wo sich der Knoten befindet bzw.
wieviele Nachfolger er hat. Hierzu ein Beispiel:
E
A
R
C
H
N
M
L
5
P
• Am einfachsten ist das Löschen eines Knotens ohne Nachfolger (C, L, P), weil nur eine Verkettung
gelöscht werden muß.
• Beim Löschen von Knoten mit nur einem Nachfolger (A, R, H, M) muß dieser nur ausgekettet, und eine
Verkettung zwischen dem Vorgänger und dem Nachfolger erstellt werden.
• Auch das Löschen eines Knotens, von dem einer der Nachfolger keinen Nachfolger hat (N), ist kein
Problem, da man den Knoten durch diesen Nachfolger ersetzen kann.
• Das einzige Problem kann es weiter oben im Baum geben, wo jeder Nachfolger weitere Nachfolger besitzt.
Das Löschen eines solchen Knotens (E) erfolgt in drei Schritten:
1. Suchen des nächstgrößeren Knotens (H); dieser kann nur einen Nachfolger haben
2. Ausgeketten dieses Knotens; nach den oben genannten Methoden
3. Ersetzen des zu löschenden Knotens durch den größeren
Nachteil dieser Funktion ist, daß bei vielen „Löschen - Einfügen“ Paaren ein leicht unausgeglichener Baum
entsteht. Dieses Problem kann man mittels „lazy deletion“ lösen. Hier wird ein Knoten nicht wirklich gelöscht,
sondern nur als gelöscht markiert, und dadurch die Baumstruktur erhalten. Das Problem, das dabei entsteht, ist
die Vergeudung der Zeit. Dies kann durch regelmäßiges Neuaufbauen des Baumes, mit Weglassen der
markierten Knoten verhindert werden.
5 Indirekte binäre Suchbäume
Für viele Anwendungen benötigt man die Suchstruktur ausschließlich zum Suchen, und nicht zum
Herumschieben von Datensätzen. Ein Beispiel wäre ein Feld mit allen Datensätzen mit Schlüsseln. Hier könnte
man den Feldindex des Datensatzes suchen, der mit einem bestimmten Schlüssel übereinstimmt. So könnte
man auch einen Datensatz mit einem bestimmten Index aus der Suchstruktur entfernen, ihn aber trotzdem noch
im Feld behalten.
Ein Weg zur Indirektheit wäre, wenn man auf die Verkettung zugunsten eines Feld verzichtet. Im Feld müssen
dann die drei folgenden Attribute vorhanden sein:
• Schlüssel
• linker Nachfolger
• rechter Nachfolger
Diese Methode wird oft bevorzugt, da man sich das Speicherzuweisen erspart. Der Nachteil ist, das unbenutzte
Verkettungen Platz im Feld vergeuden.
Die zweite Möglichkeit liegt in der Festlegung von drei Feldern für Schlüssel, linker und rechter Nachfolger.
Man kann leicht zusätzliche Felder (Information) hinzufügen, ohne das Programm für die Baumoperationen
ändern zu müssen. Der Zugriff auf solche Felder erfolgt über den Index.
6
Herunterladen