Stapel: Unterschied zwischen den Versionen
Die Seite wurde neu angelegt: „== Einführung == In der Informatik bezeichnet ein '''Stapelspeicher''' oder '''Kellerspeicher''' (kurz ''Stapel'' oder ''Keller'', häufig auch mit dem englischen Fachbegriff '''Stack''' bezeichnet) eine fundamentale, dynamische Datenstruktur[cite: 3]. Sie dient der Zwischenspeicherung von Datenobjekten in einer strikten Reihenfolge. Objekte der abstrakten Datenstruktur <code>Stack</code> verwalten beliebige Elemente nach dem '''LIFO-Prinzip''' (''Last-…“ |
Keine Bearbeitungszusammenfassung |
||
| Zeile 1: | Zeile 1: | ||
== Einführung == | == Einführung == | ||
In der Informatik bezeichnet ein '''Stapelspeicher''' oder '''Kellerspeicher''' (kurz ''Stapel'' oder ''Keller'', häufig auch mit dem englischen Fachbegriff '''Stack''' bezeichnet) eine fundamentale, dynamische Datenstruktur | In der Informatik bezeichnet ein '''Stapelspeicher''' oder '''Kellerspeicher''' (kurz ''Stapel'' oder ''Keller'', häufig auch mit dem englischen Fachbegriff '''Stack''' bezeichnet) eine fundamentale, dynamische Datenstruktur. Sie dient der temporären Zwischenspeicherung von Datenobjekten in einer streng definierten Reihenfolge und ist ein zentraler Bestandteil der objektorientierten Anwendungsentwicklung[cite: 3]. | ||
Objekte der abstrakten Datenstruktur <code>Stack</code> verwalten beliebige Elemente nach dem '''LIFO-Prinzip''' (''Last-In-First-Out''). Das bedeutet: Das Element, welches als letztes auf den Stapel gelegt wurde, wird als erstes wieder entnommen. | Objekte der abstrakten Datenstruktur (ADT) <code>Stack</code> verwalten beliebige Elemente nach dem '''LIFO-Prinzip''' (''Last-In-First-Out''). Das bedeutet: Das Element, welches als letztes auf den Stapel gelegt wurde, wird als erstes wieder entnommen. | ||
'''Alltagsanalogie:''' | |||
Ein Kellerspeicher lässt sich anschaulich mit einem Stapel von Umzugskisten oder einem Tellerstapel vergleichen. Es kann immer nur eine neue Kiste oben auf den Stapel gepackt werden (dies entspricht der Operation <code>push</code>). Ebenso kann immer nur die oberste Kiste heruntergenommen werden (entspricht der Operation <code>pop</code>). Der lesende oder schreibende Zugriff ist strukturell zwingend auf das oberste Element des Stapels beschränkt. Ein Hinzufügen oder Entfernen einer Kiste weiter unten im Stapel ist nicht möglich. | |||
== Visualisierung == | |||
Die Arbeitsweise der LIFO-Datenstruktur lässt sich durch die beiden Hauptoperationen – das Hinzufügen (Push) und das Entfernen (Pop) – am Kopfende des Stapels veranschaulichen. | |||
<html> | |||
<svg width="500" height="360" viewBox="0 0 500 360" xmlns="http://www.w3.org/2000/svg" style="background-color: transparent;"> | |||
<!-- Definition der Pfeilspitzen --> | |||
<defs> | |||
<marker id="arrow-push" viewBox="0 0 10 10" refX="5" refY="5" markerWidth="6" markerHeight="6" orient="auto"> | |||
<path d="M 0 0 L 10 5 L 0 10 z" fill="#000000"/> | |||
</marker> | |||
<marker id="arrow-pop" viewBox="0 0 10 10" refX="5" refY="5" markerWidth="6" markerHeight="6" orient="auto"> | |||
<path d="M 0 0 L 10 5 L 0 10 z" fill="#000000"/> | |||
</marker> | |||
</defs> | |||
<!-- Der Stack (von unten nach oben) --> | |||
<rect x="200" y="300" width="100" height="35" fill="#e0e0ff" stroke="#000000" stroke-width="1"/> | |||
<rect x="200" y="260" width="100" height="35" fill="#c0c0ff" stroke="#000000" stroke-width="1"/> | |||
<rect x="200" y="220" width="100" height="35" fill="#a0a0ff" stroke="#000000" stroke-width="1"/> | |||
<rect x="200" y="180" width="100" height="35" fill="#8080ff" stroke="#000000" stroke-width="1"/> | |||
<rect x="200" y="140" width="100" height="35" fill="#6060ff" stroke="#000000" stroke-width="1"/> | |||
<rect x="200" y="100" width="100" height="35" fill="#4040ff" stroke="#000000" stroke-width="1"/> | |||
<!-- Push Element (links oben) --> | |||
<rect x="40" y="20" width="100" height="35" fill="#4040ff" stroke="#000000" stroke-width="1"/> | |||
<text x="120" y="85" font-family="Arial, sans-serif" font-size="22" fill="#000000">Push</text> | |||
<!-- Push Pfeil (gebogen zum Stack) --> | |||
<path d="M 140 60 Q 190 60 195 90" fill="none" stroke="#000000" stroke-width="2" marker-end="url(#arrow-push)"/> | |||
<!-- Pop Element (rechts oben) --> | |||
<rect x="360" y="20" width="100" height="35" fill="#4040ff" stroke="#000000" stroke-width="1"/> | |||
<text x="310" y="85" font-family="Arial, sans-serif" font-size="22" fill="#000000">Pop</text> | |||
<!-- Pop Pfeil (gebogen vom Stack weg) --> | |||
<path d="M 260 85 Q 270 50 350 40" fill="none" stroke="#000000" stroke-width="2" marker-end="url(#arrow-pop)"/> | |||
</svg> | |||
</html> | |||
== Aufbau und Spezifikation (API) == | == Aufbau und Spezifikation (API) == | ||
Im Kontext der | Im Kontext der Softwaretechnologie wird diese abstrakte Datenstruktur formal über eine wohldefinierte Schnittstelle abgebildet, um die Kapselung der Daten zu gewährleisten[cite: 4]. Ein klassischer Stapel verfügt über die folgenden Methoden und Konstruktoren: | ||
=== Konstruktor === | === Konstruktor === | ||
| Zeile 22: | Zeile 57: | ||
** Das Objekt <code>pObject</code> wird oben auf den Stapel gelegt. Falls <code>pObject</code> den Wert <code>null</code> hat, bleibt der Stapel unverändert. | ** Das Objekt <code>pObject</code> wird oben auf den Stapel gelegt. Falls <code>pObject</code> den Wert <code>null</code> hat, bleibt der Stapel unverändert. | ||
* <code>void pop()</code> | * <code>void pop()</code> | ||
** Das zuletzt eingefügte (oberste) Objekt wird von dem Stapel entfernt. Falls der Stapel bereits leer ist, bleibt er unverändert. | ** Das zuletzt eingefügte (oberste) Objekt wird von dem Stapel entfernt. Falls der Stapel bereits leer ist, bleibt er unverändert (es tritt kein Fehler auf). | ||
* <code>Object top()</code> | * <code>Object top()</code> | ||
** Die Anfrage liefert das oberste Stapelobjekt zurück, ohne es zu entfernen. Der Stapel bleibt unverändert. Falls der Stapel leer ist, wird <code>null</code> zurückgegeben. | ** Die Anfrage liefert das oberste Stapelobjekt zurück, ohne es aus der Datenstruktur zu entfernen. Der Stapel bleibt unverändert. Falls der Stapel leer ist, wird <code>null</code> zurückgegeben. | ||
== Laufzeitanalyse (Komplexität) == | == Laufzeitanalyse (Komplexität) == | ||
Eine effiziente Implementierung des Stacks (beispielsweise über eine einfach verkettete Liste, bei der stets | Eine effiziente Implementierung des Stacks (beispielsweise über eine einfach verkettete Liste, bei der stets am Kopfknoten eingefügt und gelöscht wird) garantiert hochperformante Zugriffszeiten. Da ausschließlich auf das oberste Element zugegriffen wird, müssen keine iterativen Suchvorgänge durchgeführt oder nachfolgende Elemente im Speicher verschoben werden. Es ergibt sich gemäß der [[Landau-Symbole|Landau-Notation]] folgende Laufzeitkomplexität: | ||
{| class="wikitable" | {| class="wikitable" style="text-align:center;" | ||
|- | |- | ||
! Operation !! 1. Best-Case !! 2. Average-Case !! 3. Worst-Case | ! Operation !! 1. Best-Case !! 2. Average-Case !! 3. Worst-Case | ||
| Zeile 43: | Zeile 78: | ||
== Beispiel: Arbeitsweise der Stack-Operationen == | == Beispiel: Arbeitsweise der Stack-Operationen == | ||
Die | Die Veränderung des inneren Zustands eines Stacks lässt sich anhand einer sequenziellen Abfolge von Operationen nachvollziehen. In der folgenden Tabelle ist das jeweils oberste Element (Top) der Liste rechts angeordnet. | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Schritt !! Operation !! Zustand des Stacks (Bottom | ! Schritt !! Operation !! Zustand des Stacks (Bottom → Top) !! Erläuterung | ||
|- | |- | ||
| 1. || <code>Stack()</code> || <code>[ ]</code> (leer) || Nach Aufruf | | 1. || <code>Stack()</code> || <code>[ ]</code> (leer) || Nach Aufruf des Konstruktors ist der Stack initialisiert, enthält aber noch keine Elemente. | ||
|- | |- | ||
| 2. || <code>push(12)</code> || <code>[12]</code> || Nach Aufruf von <code>push(12)</code> enthält der Stack genau ein Element, nämlich die Zahl 12. | | 2. || <code>push(12)</code> || <code>[12]</code> || Nach Aufruf von <code>push(12)</code> enthält der Stack genau ein Element, nämlich die Zahl 12. | ||
| Zeile 57: | Zeile 92: | ||
| 4. || <code>pop()</code> || <code>[12]</code> || Wenn <code>pop()</code> aufgerufen wird, wird die 8 wieder entfernt – sie war die zuletzt hinzugefügte Zahl. | | 4. || <code>pop()</code> || <code>[12]</code> || Wenn <code>pop()</code> aufgerufen wird, wird die 8 wieder entfernt – sie war die zuletzt hinzugefügte Zahl. | ||
|- | |- | ||
| 5. || <code>push(15)</code> || <code>[12, 15]</code> || Nach <code>push(15)</code> besteht der Stack wieder aus zwei Elementen. Die 15 wurde zuletzt gepusht, also | | 5. || <code>push(15)</code> || <code>[12, 15]</code> || Nach <code>push(15)</code> besteht der Stack wieder aus zwei Elementen. Die 15 wurde zuletzt gepusht, liegt also oben auf dem Stack. | ||
|- | |- | ||
| 6. || <code>push(16)</code> || <code>[12, 15, 16]</code> || Nach <code>push(16)</code> besteht der Stack aus drei Elementen. Wieder ist die zuletzt gepushte Zahl ganz oben im Stack. | | 6. || <code>push(16)</code> || <code>[12, 15, 16]</code> || Nach <code>push(16)</code> besteht der Stack aus drei Elementen. Wieder ist die zuletzt gepushte Zahl ganz oben im Stack. Ein Aufruf von <code>top()</code> würde nun <code>16</code> zurückgeben. | ||
|} | |} | ||
== Implementierungsbeispiel (Java) == | == Implementierungsbeispiel (Java) == | ||
Für das tiefergehende Verständnis im | Für das tiefergehende Verständnis im Informatikunterricht ist nachfolgend eine klassische objektorientierte Implementierung des Stacks auf Basis einer einfach verketteten Liste (Knotenstruktur) dargestellt. Diese Implementierung ermöglicht das Anwenden dynamischer Datenstrukturen sowie die Untersuchung zur Effizienz und Korrektheit von Algorithmen[cite: 3]. | ||
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
| Zeile 71: | Zeile 106: | ||
private Node head; | private Node head; | ||
// Innere Knoten-Klasse zur Kapselung der | // Innere Knoten-Klasse zur Kapselung der Datenstruktur | ||
private class Node { | private class Node { | ||
Object content; | Object content; | ||