Modul 1: Algorithmen und Datenstrukturen

Werbung
IK_1_Datenstrukturen.fm Seite 29 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
Modul 1:
Algorithmen und
Datenstrukturen
„The hardware was the easy part.“
Seymour Cray,
Supercomputer
Designer,
1925–1996 [W1]
Lernziele
Algorithmen und Datenstrukturen gehören zu den klassischen Themen der
Informatik und sind unerlässlich zur erfolgreichen Analyse, zum Entwurf
und zur Implementierung (Umsetzung) eines Software-Systems. Am
Anfang stehen dabei typische Lösungsstrategien, Standardalgorithmen und
strukturierte Datentypen. Wir lernen die Methoden und Konzepte kennen,
die später für eine systematische Entwicklung von Software nötig sind.
Lösungsstrategien
Standardalgorithmen
Datentypen
1 Algorithmen 32
1.1
1.2
1.3
1.4
1.5
Definition: Was ist ein Algorithmus? 32
Beispiele für Algorithmen 32
Eigenschaften eines Algorithmus 33
Vom Problem zum Programm 33
Modellierung 35
29
IK_1_Datenstrukturen.fm Seite 30 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
1.6 Modellierungs-Notationen 36
1.6.1 Pseudo-Code-Notation 36
1.6.2 Programmablaufplan (PAP) 38
1.6.3 Struktogramme 40
1.7 Daten- und Funktionsmodellierungsmodelle 43
1.8 Kontrollelemente von Algorithmen 45
1.8.1
1.8.2
1.8.3
1.8.4
Elementare Operation (Verarbeitung) 46
Sequenz (Folge) 46
Auswahl (Selektion) 46
Wiederholung (Schleife) 47
2 Datentypen und Datenstrukturen 48
2.1
2.2
2.3
2.4
Der Begriff Datenstruktur 48
Der Begriff Datentyp 48
Syntaxdiagramme 50
Variable und Konstante 51
2.4.1 Variable 51
2.4.2 Konstante 53
2.5 Idealisierte Datentypen 54
2.6 Konkrete Datentypen 54
2.6.1 Einfache Datentypen 54
2.6.1.1 Ordinale Datentypen 54
2.6.1.2 Datentyp BOOLEAN 55
2.6.1.3 Datentyp INTEGER 55
2.6.1.4 Datentyp CHAR 55
2.6.1.5 Aufzählungstyp 56
2.6.2 Datentyp REAL 56
2.6.3 Strukturierte Datentypen 57
2.6.3.1 Mengen 57
2.6.3.2 Arrays 57
2.6.3.3 Listen 58
2.6.3.4 Matrizen 59
2.6.3.5 Tabellen und Relationen 60
2.6.3.6 Bäume und Graphen 60
2.6.3.7 Files 64
2.6.3.8 Programme 64
2.6.3.9 Objekte, Klassen und Methoden 64
2.7 Abstrakte Datentypen 65
3 Beispielalgorithmen 67
3.1 Sortieralgorithmen 67
3.1.1
3.1.2
3.1.3
3.1.4
3.1.5
3.1.6
Bubblesort 67
Selection Sort 68
Quicksort 69
Insertion Sort 69
Shell Sort 70
Heapsort 70
3.2 Suchalgorithmen 71
3.2.1 Lineare Suche 72
3.2.2 Binäre Suche 72
3.2.3 Suche auf einem binären Baum 73
4 Modulkurzzusammenfassung 74
5 Modulanhang 75
5.1 Literatur 75
5.2
5.3
5.4
5.5
5.6
5.7
5.8
30
5.1.1
5.1.2
5.1.3
5.1.4
5.1.5
Bücher 75
Artikel 76
Books in English 76
Articles in English 77
Journals 78
Internet-Links 78
Prüfungsfragen 78
Lösungen 79
Übungen 80
Diskussionsfragen 80
Timeline: Algorithmen und Datenstrukturen 80
Glossar 81
IK_1_Datenstrukturen.fm Seite 31 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
Algorithmen und Datenstrukturen sind als „einigendes Konzept“ so zentral
für die gesamte Informatik, dass sie am Anfang jeder Beschäftigung mit
Informatik stehen.
Algorithmen und Datenstrukturen gehören nahezu untrennbar
zusammen, deshalb tauchen auch überall wo über Algorithmen
gesprochen wird, die Begriffe der Datenstrukturen auf.
Ein Ziel der Informatik ist Analyse, Entwurf und die Implementierung
(Umsetzung, Realisierung, Ausprogrammierung) von Software-Systemen.
Die Wirklichkeit wird dabei in Modelle abgebildet. Dazu werden sowohl
Algorithmen als auch Daten benötigt (Bild 1.1):
Ziel: Analyse, Entwurf und
Implementierung
eines Software-Systems
Algorithmen
Daten
(Konzepte, Bedeutung,
Konstruktion, Korrektheit)
(Datentypen, Datenabstraktion,
Schnittstellen, Datenstrukturen)
Bild 1.1 Algorithmen und
Daten stehen zentral
Abstraktion
(Allgemeine Gesetze, Zusammenhänge,
Begriffsbildung, Modellbildung)
31
IK_1_Datenstrukturen.fm Seite 32 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
1 Algorithmen
1.1 Definition: Was ist ein Algorithmus?
Der Begriff Algorithmus geht etwa auf das Jahr 825 und den Araber ABU DSHAFAR
MUHAMMED IBN MUSA AL-KHWARIZIMI zurück. Er schrieb ein Lehrbuch über die
Übertragung von Gliedern einer Gleichung von einer zur anderern Seite mit dem Titel:
„Kitab al jabr w’almuqabalah“. Daraus leitete sich der Begriff Algebra ab. Aus dem
Namen des Autors wurde algorism und daraus Algorithmus (Mehrzahl: Algorithmen).
Bild 1.2 Eine Briefmarke
aus dem Jahr 1983 ist
dem „Namensgeber“
des Algorithmus gewidmet [W2, W3]
Ein Algorithmus ist eine Verarbeitungsvorschrift.
Nach BALZERT (1999) ist ein Algorithmus eine eindeutige, endliche
Beschreibung eines allgemeinen, endlichen Verfahrens zur schrittweisen
Ermittlung gesuchter Größen aus gegebenen Größen. Die Beschreibung
erfolgt in einem Formalismus mit Hilfe von anderen Algorithmen und
letztlich elementaren Algorithmen. Ein Algorithmus muss ausführbar sein.
Ein Algorithmus dient zur Lösung allgemeiner Probleme –
nicht nur zur Lösung eines speziellen Problems!
1.2 Beispiele für Algorithmen
Achtung: Was ist ein Algorithmus und was nicht? Beispiel: Ein bestimmtes
Modellflugzeug zu bauen ist ein Prozess. Aber eine allgemeine Anleitung
zum Bau von Modellflugzeugen (nicht nur eines bestimmten Flugzeugtyps)
ist ein Algorithmus. Es muss streng unterschieden werden zwischen Prozess
und Algorithmus (Bild 1.3). Die einzelnen Schritte des Algorithmus können
von einer Maschine abgearbeitet werden. In einem Computer-System stellt
diese „Maschine“ der Prozessor dar (siehe Band 1, Modul 2).
Bild 1.3 Prozesse und
Algorithmen
32
IK_1_Datenstrukturen.fm Seite 33 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
1.3 Eigenschaften eines Algorithmus
Welche Eigenschaften muss ein Verfahren (bzw. Prozess) haben, um als
Algorithmus im Sinne der Informatik gelten zu können?
Viele Verfahren im Alltag kommen dem Grundgedanken eines Algorithmus schon sehr
nahe. Allerdings sind oft die wesentlichen Eigenschaften eines „echten“ Algorithmus noch
nicht vorhanden.
Damit ein Verfahren als Algorithmus gelten kann, müssen folgende vier
Eigenschaften vorhanden sein:
•
•
•
•
Diskretheit: Der Algorithmus besteht aus einer Folge von Schritten.
Determiniertheit: Bei gleichen Startbedingungen (Anfangs- und Randbedingungen) wird stets dasselbe Endergebnis erhalten.
Eindeutigkeit: Nach jedem Schritt lässt sich der Algorithmus auf
höchstens eine Art fortsetzen.
Endlichkeit: Der Algorithmus endet nach endlich vielen Schritten.
Oft werden bestimmte Werte bewusst nicht definiert, um den Algorithmus
für verschiedene Anwendungsfälle „universell“ anwenden zu können. Diese
Werte werden dann als Parameter bezeichnet.
1.4 Vom Problem zum Programm
In der Informatik steht am Anfang eine Aufgabenstellung, ein Problem. Die
Entwicklung eines allgemeinen Planes (Algorithmus) zur Problemlösung
nennen wir Algorithmierung.
Algorithmierung
Die präzise Formulierung eines Algorithmus in einer für Computersysteme
interpretierbaren Sprache (Programmiersprache) heißt Programmierung.
Programmierung
Vom Problem über den Algorithmus zum Programm kommen wir durch
eine analytische Vorgehensweise:
Analytisches
Vorgehen
•
•
•
•
•
•
Problem formulieren,
Problemanalyse, Problemabstraktion, Problemspezifikation,
Algorithmenentwurf,
Nachweis der Korrektheit, Verifikation,
Aufwandsanalyse,
Programmierung (Implementierung).
Die Implementierung (Ausprogrammierung) eines SoftwareSystems ist der letzte (und oft kleinste) Teil einer Entwicklung!
33
IK_1_Datenstrukturen.fm Seite 34 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
Das folgende Bild veranschaulicht diesen Prozess:
Bild 1.4 Die „reale Welt“
wird in der Sprache der
Informatik mit Hilfe der
Informationstechnik
(siehe Band 1)
„abgebildet“
Führen wir nun Menschen (people), Prozessschritte (tasks) und Resultate
(deliveries) ein, dann ergibt sich das folgende Bild:
Bild 1.5 So wird in der
Informatik gearbeitet;
dieses streng systematische und strukturierte
Vorgehen ist vielen am
Anfang fremd ...
Wir werden den Softwareentwicklungsprozess im Modul 6: Softwaretechnik
& Systementwicklung noch genau besprechen. Hier konzentrieren wir uns
auf die theoretischen Grundlagen.
34
IK_1_Datenstrukturen.fm Seite 35 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
1.5 Modellierung
Ausgehend von der Auffassung der Informatik als die Wissenschaft von der
(maschinellen) Informationsverarbeitung liegt ein Schwerpunkt besonders
in der Analyse, Entwurf und Konstruktion von Informationssystemen (IS).
Da es sich bei den Problemstellungen, die von der Informatik
gelöst werden sollen, oft um hochkomplexe Probleme handelt,
ist systematisches und analytisches Vorgehen unerlässlich.
Eine Möglichkeit ist die Modellierung eines realen Systems (aus dem „real
life“) mit Hilfe eines abstrakten Modells. Die eigentliche Problemlösung
erfolgt dann in diesem Modell.
Das folgende Bild zeigt diesen Vorgang sehr anschaulich:
Bild 1.6 Problemlösung
durch Modellbildung
Modelle können oft sehr abstrakt sein (z.B. mathematische Darstellungen
durch Graphen) oder sehr nahe an der Wirklichkeit sein (top-level-view).
Letztere sollen Sachverhalte veranschaulichen, um eine Aufgliederung in
Teilproblemstellungen zu ermöglichen.
Im Software-Engineering (siehe Modul 6) werden meistens drei Modelle
unterschieden:
•
•
•
Funktionsmodell,
Datenmodell und
Benutzermodell.
35
IK_1_Datenstrukturen.fm Seite 36 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
1.6 Modellierungs-Notationen
Algorithmen lassen sich auf verschiedene Weise darstellen (visualisieren,
modellieren). Eine Darstellung durch Symbole bzw. vereinbarte Zeichen
wird Notation (aus lat. notatio = „Beschreibung“) genannt.
Notation =
Schreibweise
Selbstverständlich kann ein Algorithmus in natürlicher Sprache dargestellt
werden. Das kann in einer Aufzählung der Befehle (wie in den Beispielen in
den nachfolgenden Kapiteln) erfolgen. Zur Vereinfachung und um die
Beschreibung eindeutig zu gestalten kann die sprachliche Beschreibung
formalisiert werden, z.B.:
WENN „x größer als 0“ DANN „berechne Y“ SONST „tu nichts“.
Darstellung (Modellierung) und Beschreibung (Dokumentierung) von
Algorithmen gehören zur Programmdokumentation.
Eine gute Programmdokumentation ist eine notwendige Voraussetzung zur
Entwicklung und vor allem zur Wartung hochwertiger Programme.
Einige Möglichkeiten, komplexe Abläufe zu modellieren, sind:
•
•
•
•
Pseudo-Code-Notation,
Programmablaufplan (PAP, Flussdiagramm),
Struktogramm und
Daten- und Funktionsmodellierungsmodelle (z.B. ERM, SADT, UML).
1.6.1 Pseudo-Code-Notation
Pseudo-Code ist eine textuelle und semiformale Darstellung von Kontrollstrukturen (siehe Kapitel 1.8) in Anlehnung an problemorientierte Programmiersprachen (siehe Modul 2).
Pseudo-Code stellt unabhängig von der (später) verwendeten
Programmiersprache die logische Struktur eines Programms dar.
Die drei Hauptelemente von Pseudo-Code, die in ihrer Syntax ursprünglich
der Programmiersprache Pascal (siehe Modul 2) entliehen sind, heißen:
•
•
•
36
Sequenz,
Wiederholung und
Auswahl.
IK_1_Datenstrukturen.fm Seite 37 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
Eine Sequenz beschreibt eine Abfolge von Programmanweisungen, die in
der vorgegebenen Reihenfolge von oben nach unten abgearbeitet werden.
Eine Wiederholung ist ein Anweisungsteil, der aufgrund einer eindeutigen
Bedingung eine bestimmte Anzahl N durchlaufen wird.
Eine Auswahl stellt eine Verzweigung aufgrund einer eindeutigen Bedingung innerhalb des Programmes dar. Je nach dem Ergebnis der Bedingung
wird entweder der erste Block oder der zweite Block der Programmanweisungen ausgeführt.
Bild 1.7 Drei PseudoCode-Elemente,
ursprünglich der
Programmiersprache
Pascal entlehnt
Beispiel:
Bild 1.8 Ein Beispiel für
eine Modellierung in
Pseudo-Code. Das Prinzip dabei ist: „Wenn Bedingung erfüllt, dann tue
{Anweisungsblock},
sonst tue
{Anweisungsblock}“
Einige Vorteile von Pseudocode:
•
•
•
Schnell, einfach und jederzeit anzuwenden.
Schrittweise Verfeinerung kann durchgeführt werden.
Spezifikationen sind leicht nachvollziehbar.
Einige Nachteile von Pseudocode:
•
•
•
Es existieren keine expliziten Regeln.
Gefahr einer zu frühen Detaillierung.
Sehr rasch Verlust der Übersichtlichkeit.
Ansätze zur
Standardisierung
von Pseudocode,
siehe z.B. [W4]
37
IK_1_Datenstrukturen.fm Seite 38 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
1.6.2 Programmablaufplan (PAP)
Mit steigender Komplexität der Anforderungen wird es unmöglich, direkt
von der Problemstellung zu einem lauffähigen Programm zu kommen.
Zuallererst muss eine logische Struktur in die zu lösende
Problemstellung gebracht werden.
Ein schon relativ altes und (früher) sehr oft verwendetes Hilfsmittel für die
grafische Darstellung von Programmabläufen ist der Programmablaufplan
(PAP). Dieser ist auch bekannt als Flussdiagramm (flow chart) oder einfach Ablaufplan.
Programmablaufpläne dienen zur Visualisierung von kleineren
Problemstellungen und Algorithmen.
Die wichtigsten Bausteine eines PAP umfassen:
Bild 1.9 Die wichtigsten
Bausteine eines
Programmablaufplanes
(PAP) nach DIN 66 001,
um Lösungsansätze verständlich darzustellen
Bei der Erstellung eines Programmablaufplanes muss das Problem natürlich
schon gelöst sein. Dann können sich die Programmierer bei der Umsetzung
(Implementierung) in eine (beliebige) Programmiersprache streng an den
Ablaufplan halten und sich vollständig auf programmiertechnische Details
konzentrieren.
Größere Probleme werden in kleine, voneinander unabhängige
Teilschritte zerlegt.
38
IK_1_Datenstrukturen.fm Seite 39 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
Vorteile von Programmablaufplänen (vgl. SCANLAN (1989)):
•
•
•
Gute grafische Darstellung bei einfachen Problemstellungen.
Verschiedene Abstraktionsebenen möglich.
Alle wichtigen Kontrollstrukturen sind darstellbar.
Nachteile von Programmablaufplänen:
•
•
•
Bei komplexen Aufgabenstellungen kommt es zu einer oft nicht mehr zu
durchschauenden Programmstruktur. Deshalb werden in der Praxis eher
Struktogramme (siehe Kapitel 1.6.3) bevorzugt.
Es gibt keine direkten Symbole für Schleifenkonstrukte und Rekursionen. Daher kommt es bei großen Programmen zu Unübersichtlichkeit.
Verzweigungen und Zusammenführungen können beliebig miteinander
kombiniert werden. Das führt zu unstrukturierten Diagrammen und entspricht einer „GOTO-Spaghetti-Programmierung“.
Ein Beispiel für einen Programmflussplan:
Bild 1.10 Beispiel für
einen typischen PAP
Anmerkung: Oft wird der Programmflussplan mit dem Datenflussplan verwechselt. Ein
Datenflussplan ist eine grafische Übersicht, die Programme und Daten, die zu einer Gesamtaufgabe gehören, miteinander verbindet. Ein Datenflussplan besitzt ähnliche Symbole wie ein Programmablaufplan, aber zusätzliche Sinnbilder für Daten.
39
IK_1_Datenstrukturen.fm Seite 40 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
1.6.3 Struktogramme
In Anlehnung an die strukturierte Programmierung (siehe Modul 2) haben
Struktogramme als grafisches Hilfsmittel zur Veranschaulichung von Programmabläufen eine große Popularität erlangt.
Die Verwendung von Programmablaufplänen (PAP) verführt
zu unübersichtlicher, maschinenorientierter Programmierung
und zu undisziplinierter Verwendung von Programmsprüngen.
Daher wurden von NASSI & SHNEIDERMAN (1973) Struktogramme (Program
Structure Diagrams, PSD) entwickelt. In Anlehnung an die Erfinder werden
sie daher auch als Nassi-Shneiderman-Diagramme (NSD) bezeichnet.
Jede einzelne Aktion wird in einen Strukturblock eingetragen (Bild 1.11).
Ein Ziel war es dabei, auch die Aktionssteuerungen von Programmiersprachen in der Programmdokumentation zu berücksichtigen.
Elemente der Struktogramme nach NASSI-SHNEIDERMAN:
Bild 1.11 Die wichtigsten
Elemente nach NassiShneiderman (1973),
heute DIN 66 261;
vergleiche mit Bild 1.7
40
IK_1_Datenstrukturen.fm Seite 41 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
Die Sequenz umfasst eine beliebige Anzahl von Programmanweisungen,
die jeweils sequentiell (schrittweise hintereinander) abgearbeitet werden.
Die Wiederholung stellt einen Anweisungsblock dar, der aufgrund einer
Bedingung eine bestimmte Anzahl von Durchläufen ausführt. Bei dem hier
dargestellten Grundtyp wird die Ausführungsbedingung jeweils am Anfang
überprüft: Wenn die Bedingung erfüllt ist, dann wird der Anweisungsblock
durchlaufen. Sonst wird der nachfolgende Programmabschnitt abgearbeitet.
In Bild 1.11 gibt es zwei Modifikationen (Abänderungen zur Grundform):
•
•
Bei der ersten Modifikation wird die Abbruchbedingung am Ende der
Wiederholungsschleife abgefragt. WENN diese erfüllt wird, DANN
wird die folgende Sequenz bearbeitet, SONST wird sie wiederholt.
Die zweite Modifikation stellt eine unendliche Wiederholung („Loop“)
dar. Eingangs- und Abbruchbedingung werden nicht explizit abgefragt.
Diese Struktur wird dann zum funktionsfähigen Programmbestandteil,
wenn innerhalb des zu wiederholenden Blocks mindestens eine so genannte
Abbruchbedingung vorgesehen ist, die das Verlassen des Blocks ermöglicht.
Die Auswahl beschreibt eine Verzweigung aufgrund einer eindeutigen
Bedingung (Grundtyp).
Auch hier gibt es zwei Modifikationen:
•
•
Die erste Modifikation beschreibt die Möglichkeit einer mehrfachen
Verzweigung, bei der auf jede mögliche Bedingung eine bestimmte Alternative folgt.
Bei der zweiten Modifikation werden alle Bedingungen, die nicht explizit
aufgeführt sind, durch dieselbe Sequenz weiterverarbeitet – weil sie der
einzig verbleibende Pfad ist.
Ein Struktogramm ist ausschließlich von oben nach unten zu
durchlaufen (top-down), wobei dies auch für einzelne Blöcke
gilt. Ein Block darf immer nur durch den Eingang „betreten“
und durch den Ausgang „verlassen“ werden.
Die Blöcke können je nach dem zu lösenden Problem beliebig aufeinander
folgen oder geschachtelt werden.
Die Erstellung von Struktogrammen wird durch Software-Werkzeuge (CASE-Tools)
erleichtert, siehe z.B. [W5].
41
IK_1_Datenstrukturen.fm Seite 42 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
Einige Vorteile von Struktogrammen:
•
•
•
Struktogramme sind auf verschiedenen Abstraktionsebenen anwendbar
und ermöglichen somit eine schrittweise Verfeinerung des Entwurfs.
Durch die stark strukturierte grafische Darstellung wird die Entwicklung
von Algorithmen zur strukturierten Programmierung gefordert.
Struktogramme begünstigen die Zerlegung in hierarchische Blöcke.
Einige Nachteile von Struktogrammen:
•
•
•
Ähnlich wie das Flussdiagramm wird auch das Struktogramm bei komplexen Prozessen schnell unübersichtlich.
Wenn ein geschlossener iterativer Prozess noch als Bedingungsschleife
dargestellt werden kann („ändere das Bauteil, bis es alle Anforderungen
erfüllt“), dann erweist sich die Darstellung parallel ablaufender verteilter
Prozesse als schwierig.
Das Struktogramm ist zur Darstellung von Entwicklungsprozessen nur
bedingt geeignet.
In dem nachfolgenden Beispiel ist der gleiche Algorithmus wie bei der
Beschreibung der Programmablaufpläne dargestellt, wobei sehr rasch die
Unterschiede zwischen diesen beiden Methoden ersichtlich werden.
Bild 1.12 Das Beispiel
aus Bild 1.10 nochmal in
einem Struktogramm
dargestellt
42
IK_1_Datenstrukturen.fm Seite 43 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
1.7 Daten- und Funktionsmodellierungsmodelle
Wir wollen hier lediglich, ausgehend vom Modellierungskonzept, einige
Modellierungsmodelle erwähnen. Diese werden wir dann im Modul 6 „Software-Engineering“ genau besprechen.
Das Ziel eines Datenmodells ist, bestimmte Gegebenheiten, wie z.B. die für
einen Geschäftsprozess in einem Betrieb notwendigen Informationen, in
Datenstrukturen (siehe Kapitel 2) abbilden zu können.
Ein Datenmodell beschreibt die grundlegenden Eigenschaften, die für alle
Erscheinungen einer bestimmten (fachbezogenen) Sichtweise auf die
Wirklichkeit eine einheitliche Abbildung erleichtern. Im Datenmodell werden die grundsätzlichen Strukturen, die Beziehungen und die Eigenschaften,
die zugeordnet werden können, festgelegt.
Im Modellierungsprozess werden dann für notwendige Erscheinungen
der Wirklichkeit im Rahmen der Vorgaben des Datenmodells detaillierte
Festlegungen getroffen. Diese Festlegungen enthalten alle Definitionen
und Beschreibungen von Inhalt, Struktur und Regeln, die auf Daten über
die Erscheinungen der Wirklichkeit angewendet werden können.
Je genauer die reale Welt erfasst und im Datenmodell beschrieben wird, umso leichter ist es dann, entsprechende Regeln zur
Wahrung der Datenintegrität zu definieren.
Für die Datenmodellierung werden folgende Techniken angeboten, die eine
computergerechte Umsetzung vereinfachen und unterstützen:
•
•
•
•
Entity-Relationship-Modell (ERM),
Petrinetze (Modell zur Beschreibung von Abläufen),
Structured Analysis and Design Technique (SADT) und die
Unified Modeling Language (UML).
Als Ordnungsvorstellung zur Strukturierung von Daten in einer Datenbank
(siehe Modul 3) existieren vier Ansätze:
•
•
•
•
hierarchisches Datenmodell (ein Datensatz wird mit allen hierarchisch
von ihm abhängigen Datensätzen als Einheit betrachtet, 1:n-Beziehung),
Netzwerkmodell (ein Datensatz kann eine beliebige Anzahl übergeordneter Datensätze aufweisen, n:m-Beziehungen),
relationales Datenmodell (beruht auf der Datenstruktur „Tabelle“) und
objektorientiertes Datenmodell.
43
IK_1_Datenstrukturen.fm Seite 44 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
Das relationale Datenmodell hat besondere Bedeutung für Datenbanken
(Modul 3). Bei diesem Datenmodell stehen als Strukturelemente ausschließlich Relationen zur Verfügung, die sich durch Tabellen darstellen lassen.
Die Datensätze bilden die Zeilen, und die Merkmale des Objekts. Die
Datenfelder entsprechen den Spalten der Tabelle. Beziehungen zwischen
beliebigen Datensätzen werden über gleiche Feldinhalte hergestellt. Der
Zugriff auf bestimmte Datensätze wird über die Feldinhalte ermöglicht. Die
Benutzer arbeiten nur mit logischen bzw. mit mengenorientierten Abfragen,
wobei die physische Speicherung und der Datenzugriff für sie im Hintergrund bleiben.
Das folgende Bild gibt eine Übersicht, wo welche Basistechniken eingesetzt
werden (Details in Modul 6):
Bild 1.13 Verschiedene
Basistechniken zur
Modellierung und wo
diese hauptsächlich
verwendet werden
44
IK_1_Datenstrukturen.fm Seite 45 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
1.8 Kontrollelemente von Algorithmen
Algorithmen werden entwickelt, indem kleinste Elemente (Bausteine) zu
größeren (komplexeren) Abläufen zusammengesetzt werden.
•
•
•
•
•
•
•
•
elementare Operation (Verarbeitung)
Beispiel: „Schneide Fleisch in kleine Würfel“
Sequenz, Folge bzw. sequentielle Ausführung (ein Prozessor!)
Beispiel: „Bringe das Wasser zum Kochen, dann gib das Paket Nudeln
hinein, schneide das Fleisch, dann das Gemüse ...“
Wiederholung bzw. Schleife
Beispiel: „Rühre die Soße so lange, bis diese fest ist“
Auswahl (Selektion)
Beispiel: „Nimm Erbsen oder Dosenfrüchte“
parallele Ausführung (mehrere Prozessoren!)
Beispiel: „Ich schneide das Fleisch, du das Gemüse, er stellt inzwischen
Wasser auf, sie holt die Gewürze ...“
bedingte Ausführung
Beispiel: „Wenn Soße zu dünn, dann füge Mehl hinzu“
Unterprogramm: Die Tätigkeit wird anderswo beschrieben und ist
mehrfach benutzbar
Beispiel: „Bereite Soße so, wie im Anhang erklärt wird“
Rekursion: Anwendung desselben Algorithmus auf Teilproblem
Beispiel: Hol Wasser, Katharina! – Ein Loch ist im Eimer – Stopf es! Womit denn? – Mit Kaugummi! – Der Kaugummi reicht nicht! – Dann
nimm mehr Kaugummi! – Der Kaugummi ist zu trocken! – Hol Wasser,
Katharina ...
Mehr wird nicht gebraucht!
Es reichen sogar elementare Operationen + Sequenzen +
Wiederholungen, um alles programmieren zu können, was
überhaupt programmierbar ist!
Oft ist es aber einfach komfortabler, mehr als diese drei Grundelemente zu verwenden.
Diese Grundelemente stellen Schemata dar, die eindeutig die Reihenfolge
festlegen („kontrollieren“), wie die Anweisungen abgearbeitet werden. Daher
werden sie als Kontrollelemente bezeichnet (historisch entstanden aus den
imperativen Programmiersprachen, Modul 2, Kapitel 2.5.1.1). Im Folgenden
sehen wir uns die wichtigsten an, wobei in den jeweiligen Bildern links das
Kontrollelement in einem Flussdiagramm nach DIN 66 001, und rechts das
gleiche Kontrollelement als Struktogramm nach NASSI-SHNEIDERMAN (DIN
66 261) dargestellt wird.
45
IK_1_Datenstrukturen.fm Seite 46 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
1.8.1 Elementare Operation (Verarbeitung)
Das grundlegendste Element ist die Verarbeitung (V). Diese enthält eine
Anweisung und wird oft als Prozess oder als Aktion bezeichnet:
Bild 1.14 Kontrollelemente „Verarbeitung“;
rechts: PAP-Element,
links: Struktogrammelement
A n w e is u n g
V
1.8.2 Sequenz (Folge)
Die Sequenz (S), auch als Folge bezeichnet, besteht aus einer Anzahl n von
Verarbeitungen (V1 ... Vn), die sequentiell (nacheinander) durchlaufen und
abgearbeitet werden. Das Wesentliche dabei ist, dass eine Sequenz nach
außen wieder als eine Verarbeitung (also ein Block) dargestellt werden kann:
Bild 1.15 Kontrollelemente „Sequenz“
1.8.3 Auswahl (Selektion)
Bei der Auswahl (Selektion) werden Verarbeitungen in Abhängigkeit von
einer oder mehreren Bedingungen ausgeführt. Damit ergeben sich drei
Möglichkeiten:
•
•
•
Bild 1.16 Kontrollelemente „Selektion“; darunter die Darstellung als
Struktogramm (bei der
einseitigen Auswahl wird
einfach der Nein-Kasten
leer gelassen)
46
einseitige Auswahl (bedingte Verarbeitung),
zweiseitige Auswahl (einfache Alternative),
Mehrfachauswahl (mehrfache Alternative).
IK_1_Datenstrukturen.fm Seite 47 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
1.8.4 Wiederholung (Schleife)
Unterschieden wird zwischen Zählschleife und Bedingungsschleife. Bei den
Zählschleifen bestimmt eine Laufvariable (Schleifenzähler), die Anzahl der
Schleifendurchläufe (z.B. N = 10). Der Schleifenkopf enthält einen Startund einen Endwert. Beginnend beim Startwert wird der Schleifenzähler in
jedem Durchlauf bis zum Endwert um einen festen Wert (Schrittweite)
erhöht bzw. erniedrigt. Bei Erreichen des Endwerts wird die Schleife zum
letzten Mal durchlaufen. In sehr vielen Programmiersprachen leitet das
Schlüsselwort FOR eine Zählschleife ein (siehe Syntaxdiagramm Bild 1.20).
Anstelle von Wiederholung wird häufiger
die Bezeichnung
Schleife (loop)
verwendet; aber
auch Zyklus oder
Iteration werden
verwendet
Bei Bedingungsschleifen werden im Prinzip drei Arten unterschieden:
1) abweisende Schleife: Wiederholung mit vorangehender Bedingungsprüfung (Bild 1.18 links); 2) nicht abweisende Schleife: Wiederholung mit
nachfolgender Bedingungsprüfung (Bild 1.18 rechts) und 3) Endlosschleife:
Wiederholung ohne Bedingungsprüfung.
Bild 1.17 Bedingungsschleifen; Achtung: Eine
While-End-Schleife (Bild
mitte) bricht (im Gegensatz zu einer Zählschleife) nicht immer ab, wenn
z.B. die Endbedingung
nicht korrekt formuliert
wird – sie sind daher eine
häufige Fehlerquelle!
Durch das Kontrollelement Auswahl können Schleifen dargestellt werden:
Bild 1.18 Die Gegenüberstellung einer „Schleife S
mit Bedingung B am
Anfang“ (kopfgesteuert)
versus „Schleife mit Bedingung am Ende“ (fußgesteuert); darunter die
Darstellung mit Struktogrammen;
47
IK_1_Datenstrukturen.fm Seite 48 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
2 Datentypen und Datenstrukturen
Daten sind codierte
Informationen
Die Begriffe Information, Daten, Datentyp, Information usw. wurden in
Band 1, Modul 1 eingeführt, definiert und werden hier vorausgesetzt.
2.1 Der Begriff Datenstruktur
Der Begriff Datenstruktur (data structure) wird im weiteren Sinne oft
gleichbedeutend mit Datentyp verwendet. Im engeren Sinne wird unter
Datenstruktur jedoch der Aufbau von (zusammengesetzten) Datentypen
aus elementaren Datentypen verstanden.
Beispiel: In einer objektorientierten Sprache (siehe Modul 2) sind Datenstrukturen Anordnungen von Objekten, deren Beziehungen untereinander
nach bestimmten Gesetzmäßigkeiten aufgebaut sind. So genannte Objektklassen werden zur Datenmodellierung verwendet. Verbindungen zwischen
zwei Objekten einer Datenstruktur werden durch besondere Attribute dargestellt, die auf andere Objekte verweisen können (oft auch „Referenzieren“
genannt) – die so genannten Zeiger oder Referenzen.
In vielen nichtobjektorientierten Programmiersprachen werden statt der
Objektklassen und Objekte einfachere Konstruktoren zur Beschreibung
einer Datenstruktur verwendet.
Dabei entsprechen den Objekten die so genannten Variablen und den
Objektklassen die Datentypen.
2.2 Der Begriff Datentyp
Zur Erinnerung: Datentypen (data types) stellen in der Informatik „Zeichensorten“ dar,
mit denen bestimmte Algorithmen arbeiten. Daten bzw. Datentypen haben immer nur
eine maschineninterne Bedeutung (technische Basiszeichen). Computer können erst durch
die Information über den Datentyp die Daten entsprechend verarbeiten.
Ein Datentyp ist die Festlegung der Interpretation einer gespeicherten
(physikalischen) Bitfolge.
Datentypen können zunächst grob eingeteilt werden in (Bild 1.19):
•
•
•
idealisierte Datentypen (für den theoretischen Entwurf),
konkrete Datentypen (die „klassischen“ Datentypen) und
abstrakte Datentypen („abstrahiert“ vom konkreten Programm).
Die konkreten Datentypen können aus Grundelementen bestehen (Zahlen,
48
IK_1_Datenstrukturen.fm Seite 49 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
logische Werte, Zeichen) oder zusammengesetzt (strukturiert) sein. Wir
untergliedern sie in:
•
•
•
einfache Datentypen (Grundelemente aller weiteren Datenstrukturen),
strukturierte Datentypen (die so genannten Datenstrukturen),
Zeiger-Datentypen (dynamische Datenstrukturen).
Das folgende Bild gibt einen Überblick über Datentypen:
Bild 1.19 Systematik
der Datentypen: Hier
kommt klar der Unterschied zwischen Datentypen (konkret, einfach)
und Datenstrukturen
(wie z.B. Mengen, Arrays
usw.) heraus;
in Anlehnung an Horn
(2001), 245
Der Datentyp legt die Art der gespeicherten Information und
deren Auswertungsmöglichkeit fest.
Die Festlegung des Datentyps für eine Variable wird Definition, Deklaration
oder Vereinbarung genannt und besitzt folgenden Aufbau:
<definitionskennzeichnung> <identifikation> <typmerkmal> <definitionsabschluss>
Beispiel: In der Programmiersprache Pascal z.B. lautet eine Definition: var
Zahl integer. „Zahl“ definiert dabei eine ganzzahlige Größe.
Die Definitionskennzeichnung kann in manchen Programmiersprachen
auch entfallen. Außerdem kann das Typmerkmal der Identifikation bzw.
dem Variablennamen voranstehen.
Die Möglichkeit der digitalen Wertedarstellung der Informationen eines
Anwendungsbereiches bestimmt wesentlich auch die Anwendbarkeit eines
Computers.
49
IK_1_Datenstrukturen.fm Seite 50 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
2.3 Syntaxdiagramme
Ähnlich, wie die Struktur von Algorithmen durch Struktogramme dargestellt
werden kann (Kapitel 1.6.3), kann auch der Aufbau einer Datenstruktur
bildlich dargestellt werden. Weil die Struktur eines Textes als Syntax
bezeichnet wird, sprechen wir hier von Syntaxdiagrammen.
Der formale Aufbau einer Sprache, d.h. die Aneinanderreihung von Symbolen, wird als
Syntax bezeichnet. Die Bedeutung dieser Aneinanderreihung dagegen ist die Semantik.
Die Syntax einer Zählschleife (Kapitel 1.8.4) kann durch Syntaxdiagramme
anschaulich beschrieben werden:
Bild 1.20 Das
Grundprinzip eines
Syntaxdiagrammes
Die rechteckigen Kästchen stehen im Syntaxdiagramm für Komponenten,
deren detaillierter Aufbau offen gelassen oder an anderer Stelle beschrieben
ist und auf die wir uns durch deren Namen beziehen können.
Die runden Elemente beschreiben anonyme Teile, deren Inhalt an der
betreffenden Stelle auftreten muss (Bild 1.21).
Insbesondere beschreiben Syntaxdiagramme mit Hilfe grafischer Symbole
die Syntax einer Programmiersprache (Modul 2 und Modul 5).
Bild 1.21 Die Elemente
von Syntaxdiagrammen
Flussdiagramme und Struktogramme beschreiben den Ablauf
eines Programmes. Syntaxdiagramme beschreiben hingegen
den formalen Aufbau einer Datenstruktur und (im Modul 2)
den formalen Aufbau (Syntax) einer Programmiersprache.
Jedes Syntaxdiagramm hat genau einen Eingang und Ausgang.
In der Theoretischen Informatik (Modul 5) werden wir noch die BackusNaur-Form (BNF), benannt nach JOHN BACKUS und PETER NAUR (erstmals
zur Beschreibung der Syntax von ALGOL 60 verwendet) kennen lernen.
Backus-Naur-Form und Syntaxdiagramm sind die Standardbeschreibungstechniken für nahezu alle Programmiersprachen.
50
IK_1_Datenstrukturen.fm Seite 51 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
2.4 Variable und Konstante
2.4.1 Variable
Eine Variable hat prinzipiell drei Bestandteile:
•
•
•
Name,
Datentyp und
Wert.
Eine Variable stellt eine Art „Behälter“ für ihren Wert dar. Im Computer
wird (z.B. durch den Compiler) entsprechend dem Datentyp eine bestimmte
Speicherplatzreservierung für diesen „Behälter“ ausgeführt. Hardwaretechnisch ist eine Variable also eine Benennung von Speicherwörtern.
Die Zuweisung eines Wertes an eine Variable ist eine fundamentale Operation in Computerprogrammen.
Eine Variable zeigt eine ähnliche Verhaltensweise wie eine Wandtafel: Sie kann jederzeit
gelesen werden (liefert Wert), aber sie kann jederzeit gelöscht und überschrieben werden.
Die Zuweisung eines Wertes an eine Variable erfolgt oft durch das Operatorzeichen „=“. Zur Unterscheidung vom Gleichheitszeichen verwenden
manche Programmiersprachen auch einen Linkspfeil oder „:=“.
Wichtig ist die Unterscheidung zwischen Wertzuweisung und Gleichung
im mathematischen Sinn. Die Gleichung
X=X+1
macht in der Mathematik wenig Sinn (es existiert keine Lösung). In einer
Programmiersprache bedeutet der Ausdruck jedoch „Addiere 1 zum Wert
von X und speichere das Ergebnis wieder in X“. Kürzer: „Erhöhe X um 1“.
In einem Programm kann auf eine Variable durch Nennung ihres Namens
Bezug genommen werden. Ihr Datentyp beschreibt die Struktur und den
Wertebereich des Variablenwertes. Nur der Wert der Variablen kann durch
Operationen manipuliert werden, die für Variable dieses Datentyps in der
Programmiersprache definiert sind. Name und Datentyp einer Variablen
werden meistens explizit vor der ersten Benutzung durch eine Deklaration
festgelegt. In nahezu allen höheren Programmiersprachen müssen Variable
vor ihrer Verwendung deklariert werden. Es wird dabei der Datentyp der
Variablen und ein Bezeichner angegeben.
51
IK_1_Datenstrukturen.fm Seite 52 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
Beispiele für Variablen-Deklaration:
In der Programmiersprache FORTRAN (siehe Modul 2) können Variable
explizit deklariert werden, z.B. INTEGER V.
Variable der Datentypen INTEGER (ganze Zahl) oder REAL (rationale
Zahl als Annäherung zur reellen Zahl) können jedoch auch implizit (bei deren
ersten Benutzung) deklariert werden. Der Anfangsbuchstabe des Variablennamens entscheidet darüber, von welchem Typ die Variable ist: Beginnt er mit
I, J, K, L, M oder N, so hat die Variable den Typ INTEGER, beginnt er mit
einem anderen Buchstaben, so ist die Variable vom Typ REAL, z.B.: IV.
Die implizite Deklaration von Variablen ist eine häufige Fehlerquelle: Ein Schreibfehler
führt sofort eine neue Variable in das Programm ein.
In Pascal (siehe Modul 2) müssen alle Variablen vor der ersten Benutzung
deklariert werden. Ein Pascal-Programm besteht daher immer aus einem
Deklarationsteil und einem Ausführungsteil (dem so genannten Block).
Eine eigene Komponente des Deklarationsteils ist die Variablendeklaration,
die mit dem Wort VAR eingeleitet wird. Die Deklaration einer Variablen
„Körpergröße“ vom Datentyp REAL und einer Variablen „Personenanzahl“ vom Typ INTEGER hat daher das folgende Aussehen:
VAR Körpergröße : REAL;
Personenanzahl : INTEGER;
Ein letztes Beispiel aus der Programmiersprache C (siehe Modul 2):
INT Anzahl, Summe, I, J;
float EUR_Betrag;
Eine Verallgemeinerung sieht folgendermaßen aus:
TYP variable
oder
TYP v1, v2, ... vn (n > 1)
Mehrere Variable können kombiniert werden. Diesem Konstrukt kann ein
eigener Namen zugewiesen werden. Bei Variablen des gleichen Typs wird
von mehrdimensionalen Variablen bzw. Feldern (Arrays, Kapitel 2.6.3.2)
gesprochen.
52
IK_1_Datenstrukturen.fm Seite 53 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
2.4.2 Konstante
Konstante (Literale) sind Datenwerte, die direkt in der Anweisungsfolge
eines Programms eingetragen werden können (Standardbezeichnung, z.B.
Zahlen). Eine Konstante besteht ebenfalls aus drei Bestandteilen:
•
•
•
eindeutig festgelegter Bezeichner (Name),
Datentyp und
fester Wert aus der Wertemenge des Datentyps.
Als Konstante bezeichnet man üblicherweise auch Namen für Datenwerte (frei wählbare
Bezeichnung). Durch die eindeutige Vereinbarung von Konstanten-Namen wird ein ganz
bestimmter Datenwert mit einem Namen versehen und ist damit jederzeit zugreifbar.
Konstante repräsentieren einen bestimmten Wert, der sich zur
Ausführungszeit des Algorithmus nicht mehr ändert.
Beispiele: Pi = 3,1415 (TYP = REAL); A = 1, B = 100
Minimum = 1, Maximum = 100; Autor = „Andreas Holzinger“
Beispiel: In der Programmiersprache C (siehe Modul 2) findet man z.B. zwei
Varianten der Konstantenvereinbarungen:
const float Pi = 3,1415
#define Pi 3,1415
Die erste Form entspricht dem ANSI-Standard (siehe Band 1) und ist zu bevorzugen.
Die zweite Variante ist älter und definiert ein Makro. Vor der eigentlichen Übersetzung
wird im gesamten Text die Zeichenkette „Pi“ einfach durch die Zahl 3,1415 ersetzt.
Beispiel: In der Sprache Pascal sieht das Ganze so aus:
const pi = 3,1415;
Eine Zuweisung pi := ... ist im Gültigkeitsbereich von pi verboten.
Eine Konstante ist ein Datenelement, dessen Wert sich bei
der Ausführung eines Programms nicht ändert. Eine Variable
hingegen ist ein Datenelement, dessen Wert sich während der
Ausführung eines Programms ändern kann.
53
IK_1_Datenstrukturen.fm Seite 54 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
2.5 Idealisierte Datentypen
Idealisierte Datentypen (ideal im Gegensatz zu real) sind durch den
beschränkten (endlichen) Speicherplatz in Computern nicht darstellbar, sind
jedoch für den theoretischen Entwurf von Algorithmen hilfreich.
2.6 Konkrete Datentypen
Die konkreten Datentypen werden oft als „die“ Datentypen bezeichnet. Sie
unterteilen sich in (siehe nochmals Bild 1.18):
•
•
•
einfache Datentypen,
strukturierte Datentypen und
Zeigerdatentypen.
2.6.1 Einfache Datentypen
Einfache Datentypen sind die elementaren Grundbausteine aller weiteren
Daten. Sie sind nur als Ganzes manipulierbar und sind nicht weiter zerlegbar.
Sie unterteilen sich zunächst in zwei Unterarten:
•
•
ordinale Datentypen und
Real-Datentypen.
2.6.1.1 Ordinale Datentypen
Zu den ordinalen Datentypen zählen die elementarsten Datentypen:
•
•
•
BOOLEAN = boolesche Daten,
INTEGER = ganze Zahlen,
CHAR = Character, endliche Menge von Zeichen;
sowie durch Einschränkung abgeleitete Datentypen:
•
•
Aufzählungsdatentypen (enumeration types) und
Teilbereichsdatentypen (subrange types).
Ordinale Datentypen besitzen folgende gemeinsame Eigenschaften:
Im mathematischen
Sinn heißt eine
Zuordnung
eineindeutig, wenn
sie umkehrbar
eindeutig (bijektiv)
ist
54
•
•
•
•
•
Die Werte eines ordinalen Typs bilden eine geordnete Menge.
Jedem Wert ist eineindeutig eine Ordnungsnummer (Ordinalzahl) zugeordnet.
Es gibt einen „kleinsten“ und einen „größten“ Wert.
Die Ordinalzahl eines Wertes vom Typ INTEGER ist der Wert selbst.
Bei Aufzählungstypen hat das erste Element die Ordinalzahl 0, das
nächste 1 usw.
IK_1_Datenstrukturen.fm Seite 55 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
2.6.1.2 Datentyp BOOLEAN
Der Datentyp BOOLEAN umfasst nur die Werte TRUE (wahr) und
FALSE (falsch). Dieser ist vor allem für die Lösung logischer Probleme und
zur Konstruktion von Kontrollstrukturen von Algorithmen von Bedeutung.
In vielen Programmiersprachen werden diese Wahrheitswerte intern durch 0 bzw. 1 dargestellt. Dies gilt jedoch nicht generell und sollte deshalb nie vorausgesetzt werden.
Meistens stehen folgende logische Operatoren (vgl. mit Band 1, Modul 1)
zur Verfügung:
•
•
•
•
NOT
AND
OR
XOR
Negation,
Logisches Und,
Logisches Oder,
Exklusives Oder (Antivalenz).
2.6.1.3 Datentyp INTEGER
Der Datentyp INTEGER dient zur Darstellung ganzer Zahlen. Das sind
Ziffernfolgen ohne Dezimalpunkt mit oder ohne Vorzeichen. Mögliche
INTEGER-Konstante sind z.B. 7, -4, +378, 0, usw. Der Zahlbereich für
diesen Datentyp liegt üblicherweise zwischen zwei Konstanten MININT
und MAXINT, die von der n-Bit-Zahlendarstellung des Computersystems
abhängen, also z.B. bei einem 16-Bit-System von –32768 bis +32767.
Bei der Entwicklung mit Pseudocode wird INTEGER verwendet, wenn
man sich noch nicht auf einen endgültigen Typ festlegen will. Erst bei der
Überführung in Programmiercode wird der Typ endgültig entschieden.
Als Operationen sind „+“, „–“, „*“, „div“ (ganzzahlige Division) und
„mod“ (Rest bei ganzzahliger Division) zulässig.
2.6.1.4 Datentyp CHAR
Der Typ CHARACTER (kurz: CHAR) ist in vielen Programmiersprachen
ein vordefinierter Datentyp, dessen Wertebereich eine endliche, geordnete
Menge von Zeichen (characters) ist. Dazu gehören (mindestens) die Großbuchstaben A bis Z, die Ziffern 0 bis 9 und das Leerzeichen (blank).
Elemente des Typs CHAR werden meistens in Apostrophe (’) bzw. in
Anführungszeichen (’’) eingeschlossen. Beispiel:
’A’, ’’a’’, ’’.’’, ’$’ usw.
55
IK_1_Datenstrukturen.fm Seite 56 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
2.6.1.5 Aufzählungstyp
Aufzählungstypen können von den Programmierern selbst definiert werden.
Die allgemeine Definition eines Aufzählungstyps lautet:
type T = (t1, t2, ... tn)
T Bezeichner des Typs,
t1 ... tn mögliche Werte.
Mögliche Operationen auf T sind die Vergleichsoperationen (=, ≠ , <, >,
usw.) sowie eine Nachfolgeroperation succ (sucessor) und Vorgängerfunktion pred (predecessor).
Beispiel:
type farbe = (rot, gruen, blau)
rot < gruen < blau
2.6.2 Datentyp REAL
Der Datentyp REAL dient zur Darstellung von reellen Zahlen. Das sind
Ziffernfolgen mit Dezimalpunkt, mit oder ohne Vorzeichen sowie mit oder
ohne Exponent. Mögliche REAL-Konstante sind z.B. –2,7; 36,81;
0,23623E+2 usw. Der Buchstabe E bedeutet dabei ,,mal 10 hoch“. Der
Zahlbereich ist naturgemäß wesentlich größer als beim Typ INTEGER.
Bei der Entwicklung in Pseudocode wird der Typ REAL verwendet, wenn
feststeht, dass eine Maschinennäherung reeller Zahlen benötigt wird, die
endgültige Implementierung aber noch nicht festgelegt wird.
Variablen vom Typ REAL können als Wert prinzipiell reelle
Zahlen annehmen. Da Computersysteme allerdings nur eine
beschränkte Speicherkapazität haben, wird der Wertebereich
auf Zahlen in Gleitpunktdarstellung eingeschränkt!
Gleitpunktdarstellung (floating point) ist eine Methode zur näherungsweisen Darstellung
von reellen Zahlen in Computersystemen (siehe Band 1).
Für den Datentyp REAL sind die mathematischen Grundoperationen und
mathematische Funktionen (Sinus, Logartithmus usw.) möglich.
56
IK_1_Datenstrukturen.fm Seite 57 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
2.6.3 Strukturierte Datentypen
In der Praxis kommt man mit den einfachen Datentypen nicht aus. Daher
können in vielen Programmiersprachen beliebig kompliziert zusammengesetzte
Datenstrukturen definiert und durch eigene Variablen bezeichnet werden.
Zu den strukturierten Datentypen zählen:
•
•
•
•
•
•
Mengen, Arrays, Listen und Matrizen,
Tabellen und Relationen,
Bäume und Graphen,
Files,
Programme und
Objekte, Klassen und Methoden.
2.6.3.1 Mengen
Prinzipiell ist eine Menge definiert als eine Zusammenfassung von wohl
unterscheidbaren Objekten zu einem Ganzen (Bild 1.22). Die einzelnen
Objekte bezeichnen wir als Elemente der Menge ( x ∈ M ). Um eine endliche
Menge von Elementen eines Datentyps T zu definieren, kann der folgende
Typ in vielen Programmiersprachen deklariert werden:
set of T
Bild 1.22 Eine Menge
Eine ein-, zwei- oder mehrdimensionale Anordnung von Zahlen und Strings
in geordneten oder ungeordneten Mengen ermöglicht hohe Flexibilität zur
Manipulation von Daten.
Ein „set“ ist eine Zusammenfassung von Elementen des gleichen
Grundtyps – im Gegensatz zu Arrays aber ohne Rangordnung.
Daher können einzelne Mengenelemente auch nicht über einen
Index angesprochen werden. Die Reihenfolge der Elemente in
der Menge ist nicht definiert.
2.6.3.2 Arrays
Ein Array wird oft einfach als „Feld“ bezeichnet und ist eine geordnete
Menge gleichartiger Datentypen (Bild 1.23), wobei auf die Elemente mit
Hilfe eines Index I zugegriffen werden kann:
type arraytyp = array [I] of grundtyp
In manchen Programmiersprachen lautet das Schlüsselwort nicht Array,
sondern dim (dimension).
Bild 1.23 Ein Array
57
IK_1_Datenstrukturen.fm Seite 58 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
2.6.3.3 Listen
Eine Liste ist eine verkettete Folge von elementaren oder strukturierten
Datentypen.
Eine Liste (list) ist ein vereinfachter Graph, denn jeder Knoten außer den beiden Endknoten ist mit genau zwei anderen Knoten über je eine Kante verbunden. Von den beiden
Listenenden gehen jeweils nur eine Kante ab.
Eine lineare Liste ist eine durch Zeiger verkettete Folge von
Elementen gleichen Datentyps (üblicherweise Records). Jedes
Element, bis auf das letzte, hat genau einen Nachfolger.
Die lineare Liste ist die wichtigste dynamische Datenstruktur und wird mit
Hilfe von Zeigern realisiert. Lineare Listen werden weiter unterteilt in einfach
verketteten und doppelt verketteten Listen:
Bild 1.24 Einfach und
doppelt verkettete
lineare Liste
Listen haben folgende Eigenschaften:
•
•
•
•
Ihre Größe kann zu- und abnehmen,
beliebige Knotenzahl ist möglich,
Elemente können in effizienter Weise umgeordnet werden,
einziger Nachteil: Der Zugriff muss über den Listenkopf erfolgen.
Die Darstellung einer Liste in Pascal könnte wie folgt aussehen:
TYPE
Liste = RECORD
ende1, ende2 :^Listenknoten
END;
Listenknoten = RECORD
nutzinformation : IrgendeinTyp;
vorgänger :^Listenknoten;
58
IK_1_Datenstrukturen.fm Seite 59 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
nachfolger :^Listenknoten
END;
VAR liste: ^Liste;
l,l1,l2: ^Listenknoten;
Der Knoten, auf den ende1 zeigt, hat keinen Vorgänger, und der Knoten, auf den ende2
zeigt, hat keinen Nachfolger. In diesen Fällen besitzen die Komponenten-Vorgänger bzw.
-Nachfolger den vordefinierten Wert NIL, der anzeigt, dass die Komponenten zur Zeit
auf keinen Knoten verweisen.
Gebräuchliche Operationen auf Listen sind
•
•
•
•
•
•
das Erzeugen eines Listenknotens (neuerknoten(l1)),
das Einfügen eines Knotens nach oder vor einem anderen Knoten (liste.einfügenach(l,l1), liste.einfügevor(l,l2)),
das Entfernen eines Knotens (liste.enfernen(l)),
das Verweisen auf den Vorgänger bzw. Nachfolger (liste.nächster(l),liste.voriger(l)),
das Erfragen, ob die Liste leer ist (liste.leer), und
das Feststellen der Anzahl der Listenknoten (liste.länge).
2.6.3.4 Matrizen
Ein eindimensionales Array (Feld) entspricht einem Vektor,
ein mehrdimensionales Array einer Matrix.
Eine Matrix ist nichts anderes als eine mehrdimensional geordnete Menge
von gleichartigen Datentypen. In der Mathematik werden Matrizen für die
verschiedensten Zwecke eingesetzt. Ihre wesentlichen Merkmale sind:
•
•
die lineare Anordnung ihrer Komponenten in mehreren Dimensionen
und
die Gleichartigkeit aller Komponenten.
Matrixkomponenten werden durch einen Indexvektor identifiziert.
In Anwendungen spielt die Art und Weise, wie Matrizen im Speicher abgelegt werden
und wie der Zugriff auf ihre Komponenten erfolgt, eine wesentliche Rolle. Eine Matrix mit
z.B. 1000 x 1000 Komponenten benötigt bei der Speicherung als zweidimensionaler
Vektor eine Million Speicherzellen! Sind aber nur die Haupt- und Nebendiagonalen von
Null verschieden, so reduziert sich der Platzbedarf auf rund 3000 Speicherzellen.
59
IK_1_Datenstrukturen.fm Seite 60 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
2.6.3.5 Tabellen und Relationen
Beim Datentyp Tabelle werden Informationen unter einem bestimmten
„Schlüssel“ gespeichert. Über diesen Schlüssel können die Informationen
wieder abgerufen werden. Sowohl Schlüssel als auch Information können
dabei einen beliebigen Datentyp haben.
Relation = allg. jede
Beziehung zwischen
Datensätzen
Im Bereich der Datenbanken (siehe Band 2, Modul 3) haben relationale
Datenbanken eine lange Tradition. Daten werden in Tabellen gespeichert und
können durch Relationen verknüpft werden. Die Relationen selbst werden in
Form von Tabellen abgelegt. Eine Tabelle besteht dabei aus n Zeilen und m
Spalten, ist also eine zweidimensionale geordnete Struktur. Oft enthält eine
Spalte nur Elemente eines vorgegebenen Datentyps. Die Anzahl der Spalten
wird als konstant betrachtet und ist in der Regel bei Anlegen der Tabelle festgelegt. Die einzelnen Datensätze werden in neue Zeilen eingefügt bzw.
gelöscht. Die Zeilenzahl einer Tabelle ist damit flexibel.
2.6.3.6 Bäume und Graphen
Achtung: Graph
nicht mit Graf
verwechseln!
Bäume und Graphen sind Datenstrukturen, die aus Knoten
und Kanten bestehen: Eine Kante verbindet stets zwei Knoten
und kann somit als ein Paar von Knoten verstanden werden.
Graphen
Ein ungerichteter Graph G besteht aus zwei Mengen: einer Menge N von
Knoten (nodes) und einer Menge V von Kanten (vertices), d.h. G = (N, V).
Eine Kante a aus V verbindet stets zwei Knoten A und B aus N miteinander.
Wir schreiben a = {A,B} = {B,A}. Die Anzahl der Kanten, die mit dem
Knoten verbunden sind, wird der Grad eines Knotens genannt.
Der ungerichtete Graph in Bild 1.25 (oben) hat die Knoten A, B und C
und die Kanten a={A,B}={B,A}, b={A,C}={C,A} und c={B,C}={C,B}.
Neben den ungerichteten Graphen existieren auch gerichtete Graphen,
deren Kanten mit einer Vorzugsrichtung versehen sind. Bei ihnen sind die
Kanten a={A,B} und a´={B,A} verschieden. Dies wird in der grafischen
Darstellung durch einen Pfeil gekennzeichnet (Bild 1.25 unten). Die Anzahl
der auf einen Knoten zeigenden Kanten wird Ingrad des Knotens, die
Anzahl der aus dem Knoten herausgehenden Kanten wird Ausgrad genannt.
Bild 1.25 Ungerichteter
(oben) und gerichteter
Graph (unten)
60
Die Kanten ungerichteter Graphen stellen nur die Beziehungen zwischen
den Knoten dar, weisen jedoch keine Richtung aus. Sie können durch äquivalente gerichtete Graphen ausgedrückt werden, bei denen jeder Kante des
IK_1_Datenstrukturen.fm Seite 61 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
ungerichteten Graphen zwei Kanten des gerichteten Graphen zugeordnet
werden, die jedoch einander entgegengesetzt ausgerichtet sind.
Ein Pfad zwischen zwei Knoten A und B existiert genau dann, wenn eine
Folge aus Kanten und Knoten existiert, die von Knoten A ausgeht und zu
Knoten B führt. Ein gerichteter oder ungerichteter Graph besitzt einen
Zyklus, wenn von einem Knoten ein Pfad über mindestens einen weiteren
Knoten wieder zu dem ersten Knoten zurück existiert. Ein Graph, der keine
Zyklen besitzt, wird zyklenfrei genannt.
Im Gegensatz zu ungerichteten Kanten können gerichtete Kanten direkt auf
Variablen eines Datentyps abgebildet werden. Das ist etwas, das praktisch in
allen modernen Programmiersprachen vorkommt: der Zeiger (pointer).
Ein Knoten kann z.B. in folgender in Pascal formulierter Datenstruktur
abgebildet werden:
Pointer verweisen
(zeigen) auf Daten
TYPE
Knoten = RECORD
knoteninhalt : IrgendeinTyp;
kanten : ^Kantenliste
END;
Kantenliste = RECORD
kante : ^Knoten;
nächsteKante : ^Kantenliste
END;
VAR graph, k, k1, k2 : ^Knoten
Bäume
Ein Baum (Bild 1.26) ist ein gerichteter Graph mit Knoten, auf die – bis auf
eine Ausnahme – nur jeweils eine Kante zeigt. Die Ausnahme ist die Wurzel
des Baumes. Sie besitzt keine eingehende Kante. Von den Knoten eines
Baumes weisen ein oder auch mehrere Kanten zu weiteren Knoten, deren
ausgehende Kanten wiederum auf Knoten verweisen können. Ein Knoten
wird – zusammen mit allen über seine Kanten referenzierten Knoten, dessen
Referenzen, usw. – Teilbaum genannt (Bild 1.26).
61
IK_1_Datenstrukturen.fm Seite 62 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
Knoten, von denen keine Kanten ausgehen, werden Blätter genannt. Alle
anderen Knoten heißen innere Knoten. Die Anzahl der Kanten von der
Wurzel des Baumes zu einem Knoten heißt die Weglänge des Knotens. Die
Wurzel hat also die Weglänge 0. Die größte Weglänge, über alle Knoten
betrachtet, heißt Tiefe (bzw. Höhe) des Baumes.
B-Bäume = balanced
(ausgeglichen)
Einem Baum, dessen Knoten nur jeweils eine ausgehende Kante besitzen,
entspricht eine einfach verkettete Liste (Bild 1.24). Die häufigste Baumart ist
der binäre Baum, dessen Knoten genau zwei ausgehende Kanten besitzen,
die meist mit links und rechts bezeichnet werden. Besitzen Baumknoten
mehr als zwei ausgehende Knoten, so werden die dazugehörenden Bäume
B-Bäume oder auch Vielweg-Bäume genannt (siehe weiterführende Literatur z.B. OTTMANN & WIDMAYER (2002), SEDGEWICK (1997) oder GOODRICH
& TAMASSIA (1998)).
Bäume werden meistens dazu benutzt, um Daten im Arbeitsspeicher oder auf Massenspeichern geordnet abzulegen und schnell wiederzufinden. Aus diesem Grund besitzen die
Knoten neben den Nutzinformationen und den Verweisen auf die nachfolgenden Knoten
auch einen oder bei B-Bäumen mehrere Schlüssel, nach deren Werten der Knoten in den
Baum eingefügt wird. Zudem existiert eine Ordnungsrelation „kleiner oder gleich“. Diese
gibt Antwort darauf, ob der Schlüssel kleiner oder gleich einem anderen Schlüssel ist. Dies
ist notwendig, da Schlüssel nicht nur Zahlen sondern auch beliebig komplexere Strukturen
sein können, auf denen sich eine Ordnung definieren lässt.
Beim binären Baum besitzt jeder Knoten höchstens zwei Nachfolger. Er
lässt einfaches Suchen und Navigieren zu, z.B. mit Hilfe von Ja-Nein- bzw.
Links-Rechts-Abfragen. Sind den Nachfolgern die Wahrheitswerte „Wahr“
oder „Falsch“ zugeordnet, wird von einem logischen Baum gesprochen.
Verschiedene Suchalgorithmen auf Baumstrukturen basieren auf binären
Bäumen. Sie werden deshalb auch Suchbäume genannt.
Bild 1.26 Die Elemente
und die Struktur eines
Baumes mit der Höhe
h = 3; die Anzahl der
Kanten von der Wurzel
bis zu einem Knoten
heißt Weglänge; ein Knoten auf der Stufe i hat die
Weglänge i
62
IK_1_Datenstrukturen.fm Seite 63 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
Ein binärer Baum kann in der Sprache Pascal wie folgt dargestellt werden:
VAR wurzel, k: ^Knoten;
TYPE
Knoten = RECORD
schluessel: IrgendeinTyp;
nutzinformation: IrgendeinWeitererTyp;
links, rechts: ^Knoten
END;
Die Operationen auf einem binären Baum umfassen beispielsweise:
•
•
•
•
•
das Erzeugen eines Baumknotens (neuerknoten(k)),
das Einfügen eines Knotens in einen Baum anhand des eingetragenen
Schlüssels und der auf ihm definierten Ordnungsrelation (wurzel.einfuege(k,relation)),
das Löschen eines Knotens aus dem Baum (wurzel.loesche(k)),
das Suchen nach einem Knoten anhand eines Schlüssels (wurzel.suche(schluessel,relation)) (zurückgegeben wird ein Zeiger auf den gefundenen Knoten oder NIL, wenn kein passender Knoten gefunden wurde)
und
das Traversieren des Baumes, d.h. das Ausführen einer Operation auf jeden Baumknoten (wurzel.traversiere(operation)).
Das Suchen in einem Baum ist sehr einfach, da ab der Wurzel für jeden
besuchten Knoten nur die folgenden Fragen beantwortet werden müssen:
•
•
•
Stimmen der vorgegebene Schlüssel und der Knotenschlüssel überein,
so ist der Knoten gefunden.
Ist der vorgegebene Schlüssel von der Ordnungsrelation her kleiner als
der Knotenschlüssel, so befindet sich der gesuchte Knoten (wenn überhaupt) in dem linken Teilbaum des aktuellen Knotens.
Ist der vorgegebene Schlüssel größer als der Knotenschlüssel, so befindet sich der gesuchte Knoten (falls er existiert) im rechten Teilbaum des
aktuellen Knotens.
Bäume werden für Darstellung von Dateien und Datensätzen,
beim strukturierten Programmieren, bei Suchalgorithmen und
Entscheidungsverfahren verwendet. Der große Vorteil liegt in
der Möglichkeit, Informationen so zu ordnen, dass schnell
und systematisch auf sie zugegriffen werden kann.
63
IK_1_Datenstrukturen.fm Seite 64 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
2.6.3.7 Files
Files sind ein Konzept, das in Zusammenhang mit Betriebssystemen (siehe
Modul 2) entwickelt wurde: Ein File ist eine geordnete Menge von Bytes. Es
kann selbst z.B. Zahlen, Zeichen usw. enthalten.
Files sind lineare Folgen von Einzelelementen, die nicht in beliebiger Reihenfolge verarbeitet werden können. Files können nur sequentiell verarbeitet
werden, d.h. elementweise von vorne nach hinten.
Der Nachteil der eingeschränkten Verarbeitungsmöglichkeiten (nur sequentiell gegenüber beliebig) wird durch unbeschränkte Größe ausgeglichen:
Files können (theoretisch) beliebig viele Elemente enthalten (einschließlich
überhaupt keine). Aus technischer Sicht gibt es natürlich eine Grenze, weil
die Speicherkapazität von Computer-Systemen endlich ist. Ein File ohne
Inhalt (d.h. mit null Elementen) wird als leer bezeichnet.
2.6.3.8 Programme
Ausführbare Programme sind spezielle geordnete Mengen von Daten (physikalisch von Bytes), die der Prozessor eines Computers ausführen kann. Es
wird unterschieden zwischen Programmcode (auch „Quellcode“ genannt)
und Maschinencode (auch „Bytecode“ genannt). Der Programmcode besteht
aus Files und ist in einer künstlichen Sprache (Programmiersprache, Band 2,
Modul 3) geschrieben. Der Maschinencode hingegen besteht auf der untersten
Ebene nur aus Binärcode („0“ und „1“) und kann vom Prozessor (oder einer
virtuellen Maschine) direkt ausgeführt werden.
2.6.3.9 Objekte, Klassen und Methoden
Ab ca. 1990 wurden objektorientierte Datenstrukturen in viele Programmiersprachen eingeführt. Die Objekte sind dabei wieder verwendbare
„Bausteine“. Die Klassen sind flexible „Ansammlungen“ verschiedenster
elementarer und zusammengesetzter Datentypen. Klassen können weitere
Klassen und Programme – die so genannten Methoden – enthalten.
Prinzip der Objektorientierung ist es, Objekte nur von außen zu betrachten
und ihren inneren Aufbau zu ignorieren – ihre Struktur wird durch Klassen
festgelegt. Objekte, die nach der Struktur einer Klasse aufgebaut sind, sind
Instanzen dieser Klasse. Objekte erledigen ihre Aktivitäten praktisch in
„eigener Verantwortung“. Für die Softwareentwicklung (Modul 6) bedeutet
das mehr Konfiguration, Ergänzung und Anpassung, statt einer kompletten
Neuentwicklung.
64
IK_1_Datenstrukturen.fm Seite 65 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
2.7 Abstrakte Datentypen
Die bis jetzt vorgestellten Datentypen sind in den meisten Programmiersprachen implementiert, daher sprachen wir auch von konkreten Datentypen.
Die Einführung konkreter Datentypen war ein bedeutender Schritt in der Entwicklungsgeschichte der Programmiersprachen. Erst die Einführung von Abstraktionsmechanismen
erlauben den Programmierern, Algorithmen aus ihrer Umwelt zu entwickeln – ohne die
Details des Computersystems zu kennen.
Komplexere Datenmodelle besitzen (manchmal) auch Strukturen, die über
der Abstraktionsebene von strukturierten Datentypen liegen. Diese können
in Klassen eingeteilt werden, zu denen ein generischer Datentyp definiert
werden kann. Auf solche Datentypen können alle in einer Klasse vorkommenden
Strukturen zurückgeführt werden. Solche generischen Datentypen können in
sowohl in objektorientierten als auch in nichtobjektorientierten Sprachen
realisiert werden und werden als abstrakte Datentypen (ADT) bezeichnet.
Ein abstrakter Datentyp präsentiert sich einem Programmierer wie ein in der Programmiersprache schon verfügbarer Datentyp, auf den eine definierte Menge von Operationen
anwendbar ist. Der abstrakte Datentyp muss jedoch in nicht-objektorientierten Programmiersprachen basierend auf schon vorhandenen Datentypen definiert worden sein, wobei
Operationen in Ablaufkonstrukten der Programmiersprache ausformuliert sein müssen.
Generisch aus lat.
genus „Art, Gattung“
sind Funktionen oder
Operatoren, die
unabhängig vom
verwendeten
Datentyp immer
dieselbe Aufgabe
ausüben
Beispiel Vektor Vn als abstrakter Datentyp:
Ein Vektor Vn ist ein n-Tupel von: Vn = (v1, v2, ... vn). Um z.B. einen Punkt
im dreidimensionalen Raum zu beschreiben, kann ein Tripel V3 = (x, y, z)
verwendet werden bzw. V2 = (x, y) für einen Punkt in der Ebene. Dabei ist
es für die Operationen unerheblich, ob die Komponenten des Vektors ganze
oder reelle Zahlen sind. Mit Vektoren können neben den Grundrechenarten
Addition, Subtraktion und komponentenweiser Multiplikation mit einem
Faktor auch das Skalarprodukt und das Kreuzprodukt (für n=3) gebildet
werden. Bei allen Operationen bis auf das Skalarprodukt ist das Ergebnis
wieder ein Vektor, beim Skalarprodukt hat das Ergebnis den gleichen Typ
wie die Komponenten.
Beispiel: In der Programmiersprache Ada (Modul 2) kann ein objektorientierter Datentyp Vektor folgendermaßen beschrieben werden (Bild 1.27):
Die Deklarationen im generic-Teil legen die grundlegenden Typen, Variablen und Operationen fest, die der Anwender des abstrakten Datentyps bei
dessen Benutzung näher zu spezifizieren hat. In der package-Deklaration
werden der Datentyp vektor und die auf ihn anwendbaren Operationen
beschrieben. Diese beiden Teile sind dem Benutzer sichtbar. Der darauf fol-
65
IK_1_Datenstrukturen.fm Seite 66 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
gende Teil package body enthält die Implementation des abstrakten Datentyps. Er wird vor dem Benutzer versteckt gehalten.
Bild 1.27 Ein Beispiel in
der Sprache Ada
In diesem Beispiel lassen sich generell zwei wichtige Eigenschaften von
modernen Programmiersprachen erkennen:
•
•
der Polymorphismus von Operationen und
das Überladen von Operatoren.
Polymorphismus drückt sich im Beispiel darin aus, dass zwei Operationen
„*“ deklariert werden, die sich nur durch die Typen der Übergabe- und
Rückgabeparameter unterscheiden. Dadurch können für vom Sinn her
gleichartige Operationen auch die gleichen Namen benutzt werden.
Das Überladen von Operatoren ist die Möglichkeit, Funktionsnamen nicht
nur aus Buchstaben und Ziffern zu bilden, sondern auch Operationszeichen
wie +, *, / zuzulassen, die normalerweise nur auf Werte von elementaren
Datentypen anwendbar sind. Dadurch können Operationen mit abstrakten
Datentypen so kurz wie mit elementaren ausgedrückt werden. Allerdings
wird dadurch die Analyse von Programmen bei Fehlern erschwert, da neben
den Operatoren auch die Operandentypen für eine eindeutige Kennzeichnung der aufgerufenen Operationen notwendig sind.
66
IK_1_Datenstrukturen.fm Seite 67 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
3 Beispielalgorithmen
Die Definition „Algorithmus“ – als allgemeines Lösungsverfahren für
ein Problem – impliziert, dass zu jedem lösbaren Problem auch mindestens
ein Lösungsverfahren existiert. Es kann sogar bewiesen werden, dass zu
jedem Algorithmus unendlich viele verschiedene Algorithmen existieren, die
das gleiche Problem lösen. Um nun diese riesige Menge von Algorithmen
besser handhaben zu können, ist es sinnvoll, eine Einteilung nach Kriterien
vorzunehmen. So können z.B. Algorithmen, die ein bestimmtes Problem
lösen, zu einer eigenen Klasse zusammengefasst werden. Da auch Probleme
zu Klassen zusammengefasst werden können, ist es sinnvoll, auch auf diese
Weise eine entsprechende Einteilung von Algorithmen vorzunehmen, z.B.:
•
•
•
Sortieralgorithmen,
Suchalgorithmen,
Codierungsalgorithmen usw.
Diese Beispiele sollen nur einen groben Eindruck von der Fülle an existierenden Algorithmen, Algorithmenklassen und -klassifikationen geben. Sie erheben keinen Anspruch
auf Vollständigkeit, stellen jedoch wichtige Vertreter aus der Menge der Algorithmen dar.
3.1 Sortieralgorithmen
Das Sortieren von Objekten nach bestimmten Kriterien ist eine der häufigsten
Aufgaben, die mit Computersystemen gelöst werden. Die Sortierverfahren
können beliebige Objekte (nicht nur Zahlen) sortieren – vorausgesetzt, es
kann auf diesen eine Ordnungsrelation definiert werden.
Grundlegende Sortieralgorithmen umfassen folgende Strategien:
•
•
•
•
Sortieren durch Austauschen (z.B. Bubblesort, Quick Sort),
Sortieren durch Auswählen (z.B. Heapsort),
Sortieren durch Einfügen (z.B. lineare Listen und Bäume) und
Sortieren durch Verschmelzen (Sortieren durch Mischen).
3.1.1 Bubblesort
Bubblesort ist ein einfaches Verfahren zum Sortieren eines linearen Arrays
(Feldes). Bubblesort verfährt nach folgender Methode:
Es wird die Liste a[1] ... a[N] der Datensätze durchlaufen und dabei werden
je zwei benachbarte Elemente betrachtet: [i] und a[i+1]. Ist a[i].key >
a[i+1].key, so wird a[i] und a[i+1] vertauscht. Das Durchlaufen des Arrays
wird so lange wiederholt, bis keine Elemente mehr vertauscht wurden: Das
67
IK_1_Datenstrukturen.fm Seite 68 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
Array ist sortiert. Das Verfahren hat seinen Namen, da bei jedem Schleifendurchlauf benachbarte Elemente miteinander verglichen werden und das
jeweils größere Element nach oben „steigt“. Sie steigen wie Luftblasen nach
oben bzw. rechts auf.
Beispiel:
Feld B =
15,2,43,17,4,8,47
Nach 1. Durchlauf: 2,15,17,4,8,43,47
Nach 2. Durchlauf: 2,15,4,8,17,43,47
Nach 3. Durchlauf: 2,4,8,15,17,43,47
Keine Vertauschungen mehr bei 4. Durchlauf, d.h. das Feld ist sortiert.
3.1.2 Selection Sort
Algorithmus:
•
•
•
1. Finde das kleinste Element im Feld und tausche es mit dem ersten Element.
2. Finde das zweitkleinste Element und tausche es mit dem zweiten Element.
3. Wenn das größte Element am letzten Platz steht, ist die Datei sortiert.
Da jedes Element im Schnitt einmal bewegt wird, ist dieses Verfahren dazu
geeignet, Dateien mit sehr großen Datensätzen und kleinen Schlüsseln zu
sortieren.
Beispiel mit Zahlen:
2 8 5 7 1 (das kleinste Element wird gesucht und mit dem auf Platz 1
vertauscht)
1 8 5 7 2 (das zweitkleinste Element wird gesucht und mit dem auf Platz
2 vertauscht)
1 2 5 7 8 (das 3. Element wird gesucht, es ist auf der richtigen Position)
1 2 5 7 8 (das 4. Element wird gesucht, es ist auf der richtigen Position)
1 2 5 7 8 (das 5. Element wird gesucht, es ist auf der richtigen Position)
68
IK_1_Datenstrukturen.fm Seite 69 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
3.1.3 Quicksort
Quicksort wurde von HOARE (1960) entwickelt und ist ein Mehrzwecksortierverfahren, das in vielen Situationen weniger Ressourcen erfordert als andere
Algorithmen.
•
•
Vorteile: Quicksort läuft „in Place“ (am Ort) ab und es ist gut erforscht.
Nachteile: rekursiv, wenige Operationen, störanfällig, innere kurze
Schleife.
Algorithmus:
Quicksort besteht im Wesentlichen aus dem Zerlegen der Datei in zwei Teilen und dem anschließenden Sortieren der Teile unabhängig voneinander.
•
•
•
•
•
•
1. Zuerst wird ein beliebiges Element gewählt, das in die richtige Position
gebracht werden soll.
2. Dann wird das Feld von links untersucht, bis ein größeres Element
gefunden wird.
3. Danach wird das Feld von rechts untersucht, bis ein kleineres oder
gleiches Element gefunden wird.
4. Jetzt werden die beiden Elemente vertauscht.
5. Wenn sich die beiden Zeiger treffen, wird das Element, dass auf die
richtige Position gebracht werden soll, mit dem Element vertauscht, das
sich am weitesten links von der rechten Seite befindet.
6. Danach wird dieser Vorgang jeweils für die daraus entstehenden Teildateien rekursiv angewendet, bis sie vollständig sortiert sind.
3.1.4 Insertion Sort
Der Insertion Sort arbeitet schneller (N²/4 Vergleiche und N²/8 Austauschoperationen) als der Bubblesort Algorithmus (N²/2 Vergleiche und N²/2
Austauschoperationen). Der Selection Sort benötigt N²/2 Vergleiche und N
Austauschoperationen. Allerdings sind alle diese Sortierverfahren nicht für
größere Datenmengen geeignet.
Algorithmus:
•
•
•
1. Betrachte ein Element.
2. Füge dieses Element an seinen jeweils richtigen Platz zwischen den
bereits betrachteten Elementen ein, indem das größere um eine Position
nach rechts bewegt und das Element dann auf dem freigewordenen
Platz eingefügt wird (Bild 1.22) .
3. Das Ende ist dann erreicht, wenn man das letzte Feld betrachtet hat.
Bild 1.28 Beispiel für
die Wirkungsweise von
Insertion Sort
69
IK_1_Datenstrukturen.fm Seite 70 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
3.1.5 Shell Sort
Shell Sort ist eine Erweiterung des Insertion Sort, wobei aber eine Erhöhung
der Geschwindigkeit dadurch erzielt wird, dass weit entfernte Elemente ausgetauscht werden können.
Algorithmus:
•
•
•
•
•
1. Zuerst wird ein bestimmter Abstand zwischen den jeweiligen Elementen gesucht, z.B. 4 Elemente Unterschied.
2. Es werden das 1. und das 5. Element verglichen, das 2. und das 6. Element verglichen usw. (eine solche Datei wird „4-sortiert“ genannt).
3. Die Elemente werden – wenn es notwendig ist – vertauscht.
4. Wenn man am Ende der Datei ist, so wird ein neuer, kleinerer Abstand
zwischen den Elementen gewählt.
5. Wenn der Abstand nur mehr aus 1 Element Unterschied besteht, wird
die gesamte Datei mit dem Bubblesort sortiert.
Bei Dateien mit vielen Elementen wird der Abstand entsprechend größer
gewählt. Die besten Abstände (also der Abstand bei dem das Sortieren am
effizientesten ist) zwischen den einzelnen Elementen Abstand * 3 +1.
Die Beschreibung der Effizienz von Shell Sort ist sehr ungenau, da bis jetzt
noch niemand den Algorithmus genau analysieren konnte. Bis zu etwa 5000
Elementen ist der Shell Sort von allen bisherigen Sortierverfahren das beste
und wird auch bei vielen Anwendungen benutzt.
3.1.6 Heapsort
Oft müssen andere Operationen, wie das Einfügen, Löschen des größten
Elements, Ersetzen, Verändern, Löschen eines beliebigen Elements und das
Zusammensetzen mehrerer Daten, möglich sein. Dafür eignet sich der
Heapsort („Sortierung von Haufen“) sehr gut. Der Algorithmus wurde von
WILLIAMS (1964) entwickelt und basiert auf dem Treesort-Verfahren von
FLOYD (1962).
Die Datenstruktur des Heaps ist ein vollständiger, nicht sortierter, binärer
Baum. Dieser Baum muss zwei Bedingungen erfüllen:
•
•
70
1. Jeder Knoten muss größer als sein Nachfolger sein, das heißt, der
größte Schlüssel ist die Wurzel.
2. Wenn ein Knoten die Position j hat, muss sein Nachfolger die Position
j*2 oder j*2+1 haben.
IK_1_Datenstrukturen.fm Seite 71 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
Algorithmus:
Zunächst wird ein Heap aufgebaut, der die zu sortierenden Elemente enthält:
•
•
•
•
•
•
1. An der (abrunden(letzten Position/2)) suchen (z.B. 9/2=4.5 -> 4).
2. Heapbedingung überprüfen (Element an Position j muss größer sein
als Element an der Position j*2 und j*2+1).
3. Wenn es notwendig ist, Elemente tauschen.
4. Punkt 2 und 3 wiederholen, bis man die verglichenen Elemente nicht
mehr tauschen muss.
5. Position um 1 vermindern.
6. Punkt 1 bis 5 wiederholen, bis man die erste Position erreicht.
Danach werden sie in der richtigen Reihenfolge entfernt, und das jeweilige
entfernte Element wird gespeichert („Top-down-Heap“):
•
•
1. Erstes Element mit letztem Element tauschen.
2. Neuen Heap aufbauen, ohne das letzte Element zu berücksichtigen.
Der Heapsort ist eine effiziente Sortiermethode (es gibt keine
ungünstigen Fälle, es ist kein zusätzlicher Speicherplatz notwendig), allerdings ist er nur halb so schnell wie der Quicksort.
Die für eine Sortierung benötigte Zeit t = n × log (n), hängt also von der
Anzahl n der zu sortierenden Elemente ab. Damit gehört Heapsort zu den
schnellsten Sortieralgorithmen. Nur Quicksort ist noch schneller.
3.2 Suchalgorithmen
Suchen wird in der Informatik als Auffinden einer bestimmten Information
definiert. Dieser Begriff ist abzugrenzen von Durchsuchen (z.B. einer Datei
oder eines Datenträgers), bei dem jedes Element genau einmal bearbeitet
wird. Suchalgorithmen sind Verfahren um in einem Datenbestand Objekte
zu finden, die eine bestimmte Bedingung – das Suchkriterium – erfüllen.
Die folgenden Suchalgorithmen sind verbreitet:
•
•
•
lineare (sequentielle) Suche,
binäre Suche und die
Suche auf einem (binären) Baum.
Oft wird in diesem Zusammenhang von einem „Schlüssel“ gesprochen, der
die Datensätze kurz und eindeutig kennzeichnen soll.
71
IK_1_Datenstrukturen.fm Seite 72 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
3.2.1 Lineare Suche
Bei einer linearen Suche werden sequentiell (nacheinander) die Objekte
eines „Behälters“ durchgesehen – bis ein Objekt gefunden wird, das das
Suchkriterium erfüllt. Anschließend wird in gleicher Weise fortgesetzt, um
weitere Objekte zu finden. Dieses Verfahren ist einfach, aber zeitaufwendig.
Allgemein lässt sich dieses Suchproblem so definieren:
•
•
In einem Behälter B befindet sich eine Anzahl von Elementen,
Prüfe, ob ein Element e ∈ Β existiert, das die Eigenschaft E(e) erfüllt
„Behälter“ kann dabei eine beliebige Datenstruktur sein, wie z.B. Listen,
Arrays, Mengen, Bäume, Graphen usw., der Anfangszustand des Behälters
kann sowohl sortiert als auch unsortiert sein. Jedes Element wird einmal
„angefasst“ und überprüft. Der ungünstigste Fall (worst case) kann dann
sein, das alle Elemente einmal angefasst werden müssen.
Vorteile:
•
•
einfach zu programmieren;
ist bei einfachen und kurzen Listen schneller als die binäre Suche.
Nachteile:
•
•
ist nicht geeignet für das Suchen in verketteten Listen und Bäumen;
Zeitaufwand ist linear ansteigend, das Verfahren wird daher langsam.
3.2.2 Binäre Suche
In einer auf- oder absteigend sortierten Liste wird fortgesetzt der Bereich
halbiert, in dem sich ein gesuchtes Objekt noch befinden kann. Ein solcher
Algorithmus arbeitet schnell, da er bereits mit wenigen Schritten zum Ziel
kommt: Eine Verdoppelung der Objektzahl erfordert im Mittel lediglich
eine zusätzliche Bereichshalbierung.
Beispiel: Suchen einer Telefonnummer in einem Telefonbuch:
•
•
•
•
72
Aufschlagen des Telefonbuches in der Mitte,
nachschauen, ob der gesuchte Name in der linken oder in der rechten
Hälfte vorkommt,
dann wiederholen des Vorganges mit der entsprechenden Hälfte, bis der
Name gefunden wird.
Meistens (spätestens) nach dem 10. Vergleich fündig.
IK_1_Datenstrukturen.fm Seite 73 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
3.2.3 Suche auf einem binären Baum
Alle Objekte werden aus einer nach dem Suchkriterium vorsortierten und
aufsteigend nummerierten Liste in einen binären Baum (Kapitel 2.6.3.6) so
einsortiert, dass die Einträge des linken Teilbaums kleinere Listennummern
als der übergeordnete Knoteneintrag aufweisen. Entsprechend weisen die
Einträge des rechten Teilbaums nach dem Knoteneintrag größere Einträge
auf und das für alle Knoten. Die Suche beginnt oben an der Baumwurzel:
Erfüllt der Wurzeleintrag das Suchkriterium, ist die Suche sofort erfolgreich.
Wird nach einer kleineren Nummer als der des Wurzeleintrags gesucht, dann
verzweigt man im Baum nach links in die nächste Knotenebene, sonst nach
rechts. Anschließend setzt man an dem erreichten Knoten in gleicher Weise
fort. Diese Suche endet nach (spätestens) so vielen Abfragen, wie Verzweigungen möglich sind. Damit ist die Suche auf einem binären Baum ein sehr
effizienter Suchalgorithmus.
Bei der Suche auf nicht binären, aber geordneten Baumstrukturen wie z.B.
dem B-Baum können ähnliche Suchalgorithmen verwendet werden. Aber
zusätzlich werden alle Nachfolger eines Knotens wie bei einer geordneten
Liste durchsucht.
Ein Baum, der speziell für effizientes Suchen eingerichtet ist,
wird als Suchbaum bezeichnet.
Von Bedeutung ist auch das Hash-Verfahren: Dabei handelt es sich um ein
kombiniertes Speicherungs- und Suchverfahren, bei dem Datensätze
gestreut gespeichert und die Adressen von Datensätzen aus den zugehörigen
Schlüsseln errechnet werden. Gestreute Speicherung von Datensätzen
bedeutet, dass bezüglich einer Nummerierung der gespeicherten Datensätze
nach den Schlüsseln Lücken auftreten. Solche sind praktisch nur mit großem
Aufwand zu vermeiden, wenn die Menge aller möglichen Schlüssel wesentlich größer als die Zahl der Datensätze ist. Eine direkte Adressierung der
Datensätze nach den Schlüsseln hätte aber den Nachteil, dass unnötig viele
Speicheradressen zur Verfügung gestellt werden müssen. Daher werden
beim Hash-Verfahren die Datensätze einem Speicherbereich von passender
Größe zugeteilt. Die Adressierung erfolgt indirekt, d.h. über eine Vorschrift,
wie sich die Adresse aus den Schlüsseln berechnet. Diese Vorschrift wird
Hash-Funktion genannt und wird so entworfen, dass die Adressen schnell
zu berechnen sind und sich die Adressen gleichmäßig auf den Speicherbereich
verteilen. Die Auflistung aller Funktionswerte einer Hash-Funktion wird
Hash-Tabelle genannt. Hash-Verfahren werden auch bei Schachprogrammen verwendet, um identische Stellungen zu finden, die durch verschiedene
Zugfolgen (die die Schlüssel bilden) erreicht werden.
73
IK_1_Datenstrukturen.fm Seite 74 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
4 Modulkurzzusammenfassung
Algorithmen und Datenstrukturen sind zentral für die ganze Informatik. Ein
Algorithmus dient zur Lösung allgemeiner Probleme und muss diskret,
determiniert, eindeutig und endlich sein.
Darstellungsmöglichkeiten von Algorithmen umfassen die Pseudo-Code
Notation, Programmablaufplan (PAP) und Struktogramm. Im SoftwareEngineering (Modul 6) wird hauptsächlich mit so genannten Daten- und
Funktionsmodellierungsmodellen gearbeitet (ERM, SADT, UML).
Algorithmen werden entwickelt, indem Kontrollelemente zu komplexeren
Abläufen zusammengesetzt werden: Elementare Operation (Verarbeitung),
Sequenz (Abfolge) und Wiederholung (Schleife) reichen, um alles programmieren zu können, was überhaupt programmierbar ist. Komfortabel sind
zusätzlich die parallele Ausführung, bedingte Ausführung, Unterprogramm
und Rekursion.
Eine Konstante ist ein Datenelement, dessen Wert sich bei der Ausführung
eines Programms nicht ändert. Eine Variable hingegen ist ein Datenelement,
dessen Wert sich während der Ausführung eines Programms ändern kann.
Der Datentyp legt die Art der gespeicherten Information und deren Auswertemöglichkeit fest. Idealisierte Datentypen sind durch den beschränkten Speicherplatz in Computern nicht darstellbar, können jedoch für den
theoretischen Entwurf von Algorithmen hilfreich sein.
Die konkreten Datentypen werden oft als „die“ Datentypen bezeichnet
und unterteilen sich in einfache Datentypen, strukturierte Datentypen und
Zeigerdatentypen.
Einfache Datentypen sind die elementaren Grundbausteine aller weiteren
Daten. Sie sind nur als Ganzes manipulierbar und nicht weiter zerlegbar. Sie
unterteilen sich in zwei Unterarten: ordinale Datentypen und Real-Datentypen. Zu den ordinalen Datentypen zählen: BOOLEAN, INTEGER und
CHAR sowie die durch Einschränkung abgeleiteten Aufzählungsdatentypen
und Teilbereichsdatentypen.
In vielen Programmiersprachen können beliebig zusammengesetzte Datenstrukturen definiert und durch eigene Variable bezeichnet werden. Zu den
strukturierten Datentypen zählen: Mengen, Arrays, Listen und Matrizen;
Tabellen und Relationen; Bäume und Graphen; Files; Programme und
Objekte, Klassen und Methoden.
74
IK_1_Datenstrukturen.fm Seite 75 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
5 Modulanhang
5.1 Literatur
5.1.1 Bücher
AHO, ALFRED V.; ULLMAN, JEFFREY D. (1997): Informatik. Datenstrukturen und Konzepte der Abstraktion. Bonn: MITP-Verlag.
BALZERT, HELMUT (1999): Lehrbuch Grundlagen der Informatik: Konzepte und Notationen
in UML, Java und C++, Algorithmik und Softwaretechnik und Anwendungen. Berlin u.a.:
Spektrum Akademischer Verlag. 467–652.
BREUER, HANS (1995): dtv-Atlas zur Informatik: Tafeln und Texte. München: Deutscher
Taschenbuch Verlag. 53–55.
ERNST, HARTMUT (2000): Grundlagen und Konzepte der Informatik. Braunschweig:
Vieweg. 410–661.
FUTSCHEK, GERALD (1989): Programmentwicklung und Verifikation. Berlin, Heidelberg,
New York: Springer.
GOLDSCHLAGER, LES; LISTER, ANDREW (1990): Informatik – Eine moderne Einführung.
3. Auflage. München, Wien u.a.: Hanser Prentice Hall International.
GOOS, GERHARD (2001): Vorlesungen über Informatik Band 2: Objektorientiertes Programmieren und Algorithmen. 3. Auflage. Berlin: Springer.
GUMM, HEINZ-PETER; SOMMER, MANFRED (2000): Einführung in die Informatik.
4. Auflage. München, Wien: Oldenbourg. 271–356.
HEUN, VOLKER (2000): Grundlegende Algorithmen: Einführung in den Entwurf und die Analyse effizienter Algorithmen. Braunschweig: Vieweg.
JUNGNICKEL, D. (1990): Graphen, Netzwerke und Algorithmen. Mannheim, Wien, Zürich: BI-Wissenschaftsverlag.
MEHLHORN, K. (1988): Datenstrukturen und effiziente Algorithmen. Band 1: Sortieren und
Suchen. Stuttgart: Teubner.
OTTMANN, THOMAS; WIDMAYER, P. (2002): Algorithmen und Datenstrukturen. Heidelberg u.a.: Spektrum.
OTTMANN, THOMAS, Hrsg. (1998): Prinzipien des Algorithmenentwurfs. Heidelberg:
Spektrum.
SAAKE, GUNTER; SATTLER, KAI-UWE (2001): Algorithmen & Datenstrukturen: Eine
Einführung mit Java. Hannover: Heise.
75
IK_1_Datenstrukturen.fm Seite 76 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
SEDGEWICK, ROBERT (1992): Algorithmen in C++. Bonn: Addison Wesley.
SOLYMOSI, ANDREAS; GRUDE, ULRICH (2000): Grundkurs Algorithmen und Datenstrukturen: Eine Einführung in die praktische Informatik mit Java. Stuttgart: Vieweg.
WIRTH, NIKOLAUS (1983): Algorithmen und Datenstrukturen. Stuttgart: Teubner.
5.1.2 Artikel
BRANDENBURG, FRANZ J.; JÜNGER, MICHAEL; MUTZEL, PETRA (1997): Algorithmen zum automatischen Zeichnen von Graphen. Informatik-Spektrum, Vol. 20, Iss. 4,
199–207.
RAUH, OTTO (1995): ERMded – eine Erweiterung des Entity-Relationship-Modells
zur Modellierung deduktiver Informationssysteme. Informatik Forschung und Entwicklung, Vol. 10, Iss. 3, 128–138.
ZIEGLER, BERNHARD (1996): ESS – Ein schneller Algorithmus zur Mustersuche in
Zeichenfolgen. Informatik Forschung und Entwicklung, Vol. 11, Iss. 2, 69–83.
ZELLER, ANDREAS (2001): Datenstrukturen visualisieren und animieren mit DDD.
Informatik Forschung und Entwicklung, Vol. 16, Iss. 2, 65–75.
5.1.3 Books in English
AHO, A. V. ; HOPCROFT, J. E.; ULLMAN, J. D. (1974): The Design and Analysis of Computer Algorithms. Reading (MA): Addison-Wesley.
AHUJA, RAVINDRA K.; MAGNANTI, THOMAS L.; ORLIN, JAMES B. (1993): Network
Flows: Theory, Algorithms, and Applications. Englewood Cliffs (NJ): Prentice Hall.
CORMEN, THOMAS H.; LEISERSON, CHARLES E.; RIVEST, RONALD L. (1990): Introduction to Algorithms. Boston (MA): MIT Press.
DAHL, O.-J.; DIJKSTRA, E. W.; HOARE, C. A. R. (1972): Structured Programming. London, New York: Academic Press.
GOODRICH, M. T.; TAMASSIA, R. (1998): Data Structures and Algorithms in Java. New
York: Wiley.
HOROWITZ, ELLIS; SAHNI, SARTAJ (1983): Fundamentals of Data Structures. New York:
Computer Science Press.
KNUTH, D. E. (1973): The Art of Computer Programming: Volume 1: Fundamental Algorithms. Reading (MA): Addison Wesley.
KNUTH, D. E. (1981): The Art of Computer Programming: Volume 2: Seminumerical algorithms. Reading (MA): Addison Wesley.
76
IK_1_Datenstrukturen.fm Seite 77 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
KOZEN, DEXTER C. (1991): The design and analysis of algorithms (Texts and Monographs in
Computer Science). Berlin et al.: Springer.
MEHLHORN, KURT (1984): Data structures and algorithms 1: Sorting and searching
(EATCS Monographs on Theoretical Computer Science). Berlin et al.: Springer.
MEHLHORN, KURT (1984): Data structures and algorithms 2: Graph algorithms and NPCompleteness (EATCS Monographs on Theoretical Computer Science). Berlin et al.: Springer.
PAPADIMITRIOU, CHRISTOS H.; STEIGLITZ, KENNETH (1982): Combinatorial optimization: Algorithms and complexity. Englewood Cliffs (NJ): Prentice-Hall.
SEDGEWICK, ROBERT (1997): Algorithms in C. Reading (MA): Addison-Wesley.
SHAFFER, CLIFFORD A. (1997): A Practical Introduction to Data Structures and Algorithm
Analysis: C++ Version. London: Prentice Hall.
SHAFFER, CLIFFORD A. (1998): A Practical Introduction to Data Structures and Algorithm
Analysis: Java Edition. London: Prentice Hall.
STANDISH, THOMAS (1998): Data Structures in Java. Addison-Wesley.
5.1.4 Articles in English
AGARWAL, PANKAJ K.; SHARIR, MICHA (1998): Efficient Algorithms for Geometric
Optimization. ACM Computing Surveys, 30 (4), 412–458.
BOYER, R. S.; MOORE, J. S. (1977): A fast string searching algorithm. Communcations
of the ACM, 20 (10).
GAEDE, VOLKER; GÜNTHER, OLIVER (1998): Multidimensional Access Methods.
ACM Computing Surveys, 30 (2), 170–231.
GUPTA, P.; CHAKRABARTI, P. P.; GHOSE, S. (1992): The Towers of Hanoi: Generalizations, Specializations, Algorithms. Int. Journal of Computer Mathematics, 46, 149–161.
HOARE, C. A. R. (1961): Algorithm 64: Quicksort. Communications of the ACM, Vol. 4,
Iss. 7, 321.
HOARE, C. A. R. (1971): Proof of a program: FIND. Communications of the ACM, Vol.
14, Iss. 1, 39–45.
SCANLAN, D. A. (1989): Structured flowcharts outperform pseudocode: An experimental comparison. IEEE Software, 6, 28-36.
WIERINGA, ROEL (1998): A Survey of Structured and Object-Oriented Software
Specification Methods and Techniques. ACM Computing Surveys, 30 (4), 459–527.
77
IK_1_Datenstrukturen.fm Seite 78 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
5.1.5 Journals
Algorithmica (ISSN: 0178-4617 printed version; ISSN: 1432-0541 electronic version)
| Springer
Theory of Computing Systems, vorher: Mathematical Systems Theory (ISSN 14324350) | Springer
Acta Informatica (ISSN: 0001-5903 printed version; ISSN: 1432-0525 electronic version) | Springer
Discrete Applied Mathematics (ISSN: 0166-218X) | Elsevier
Information Processing Letters (ISSN: 0020-0190) | Elsevier
Informatik Forschung und Entwicklung (ISSN 0178-3564) Springer
5.2 Internet-Links
Aktualisierte Internet-Links zu diesem Modul sind auf der Buchhomepage
www.basiswissen-it.at unter IK – Modul 1: Algorithmen & Datenstrukturen verfügbar!
5.3 Prüfungsfragen
Fragen-Typ 1: Dichotome Ja/Nein-Entscheidungen:
01
02
03
04
05
06
07
08
09
10
78
Determiniertheit heißt, dass bei gleichen Anfangs- und Randbedingungen stets dasselbe Endergebnis erhalten wird.
Ein Datentyp beschreibt eine Verzweigung aufgrund einer eindeutigen
Bedingung (Grundtyp).
Struktogramme beschreiben den formalen Aufbau einer Datenstruktur
und den formalen Aufbau einer Programmiersprache.
Konstante repräsentieren einen Wert, der vor Programmausführung
festgelegt wird und sich zur Ausführungszeit des Algorithmus ändert.
Der Datentyp BOOLEAN umfasst nur die Werte TRUE (wahr) und
FALSE (falsch).
Der Datentyp INTEGER ist ein vordefinierter Datentyp und dient
zur Darstellung von reellen Zahlen.
Ein eindimensionales Array wird auch Feld genannt und entspricht
einem Vektor, ein mehrdimensionales Array entspricht einer Matrix.
Bubblesort ist eine Erweiterung des Insertion Sort und ist ein
vollständiger binärer Baum.
Ein Baum ist ein gerichteter Graph mit Knoten, auf die, bis auf eine
Ausnahme, nur jeweils eine Kante zeigt.
Quicksort besteht aus dem Zerlegen einer Datei in zwei Teile und dem
anschließenden Sortieren der Teile unabhängig voneinander.
ˆ Ja
ˆ Nein
ˆ Ja
ˆ Nein
ˆ Ja
ˆ Nein
ˆ Ja
ˆ Nein
ˆ Ja
ˆ Nein
ˆ Ja
ˆ Nein
ˆ Ja
ˆ Nein
ˆ Ja
ˆ Nein
ˆ Ja
ˆ Nein
ˆ Ja
ˆ Nein
IK_1_Datenstrukturen.fm Seite 79 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
Fragen-Typ 2: Mehrfachauswahlantworten (Multiple Choice):
01
02
03
04
05
06
07
08
Beispiele für Algorithmen sind ...
ˆ a) ... das Sortieren von Briefen.
ˆ b) ... die Anleitung zur Behebung von Startproblemen bei Autos.
ˆ c) ... die Regeln der Differentialrechnung.
ˆ d) ... die Berechnung der Oberfläche einer Dose.
Zu den elementaren Datentypen zählen ...
ˆ a) ... Graphen.
ˆ b) ... Byte.
ˆ c) ... Zeichen.
ˆ d) ... Mengen.
Es kann alles programmiert werden mit den Elementen ...
ˆ a) ... Rekursion + Verarbeitung + Sequenz.
ˆ b) ... Verarbeitung + Wiederholung + Sequenz.
ˆ c) ... Verarbeitung + Auswahl + Sequenz.
ˆ d) ... Sequenz + Wiederholung + bedingter Ausführung.
Struktogramme ...
ˆ a) ... sind auch bei komplexen Problemstellungen sehr übersichtlich.
ˆ b) ... sind gut zur Darstellung parallel ablaufender Prozesse geeignet.
ˆ c) ... sind zur Darstellung von Entwicklungsprozessen gut geeignet.
ˆ d) ... dienen zur Veranschaulichung von Programmabläufen.
Zu den strukturierten Datentypen zählen ...
ˆ a) ... Mengen.
ˆ b) ... Graphen.
ˆ c) ... Real-Datentyp.
ˆ d) ... Files.
Ordinale Datentypen umfassen ...
ˆ a) ... Aufzählungsdatentypen.
ˆ b) ... Zeigerdatentypen.
ˆ c) ... Objekte, Klassen und Methoden.
ˆ d) ... Tabellen und Relationen.
Ausführbare Programme sind ...
ˆ a) ... spezielle geordnete Mengen von Daten.
ˆ b) ... spezielle geordnete Mengen von (physikalischen) Bytes.
ˆ c) ... Ansammlungen elementarer Datentypen.
ˆ d) ... lineare Folgen von Einzelelementen.
Gebräuchliche Operationen auf Listen sind ...
ˆ a) ... das Erzeugen eines Listenknotens.
ˆ b) ... das Erzeugen eines Baumknotens.
ˆ c) ... das Traversieren des Baumes.
ˆ d) ... das Verweisen auf den Vorgänger bzw. Nachfolger.
5.4 Lösungen
Lösungen zu Fragen-Typ 1: 01 Ja; 02 Nein; 03 Nein; 04 Nein; 05 Ja; 06 Nein;
07 Ja; 08 Nein; 09 Ja; 10 Nein
Lösungen zu Fragen-Typ 2: Richtig sind: 01 b) c); 02 b) c); 03 b); 04 d); 05
a) b) d) 06 a); 07 a) b); 08 a) d
79
IK_1_Datenstrukturen.fm Seite 80 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
5.5 Übungen
•
•
•
Entwickeln Sie einen Algorithmus, der zwei Namenslisten vergleicht und
die doppelt vorhandenen Namen in eine dritte Liste schreibt. Bei mehrfachem Aufscheinen gleicher Namen soll dieser nur einmal aufscheinen.
Entwickeln Sie für eine (beliebige) Aufgabenstellung einen Programmablaufplan und ein Struktogramm. Vergleichen Sie nun die beiden Darstellungen und überlegen Sie deren Vorteile und Nachteile!
Vergleichen Sie verschiedene Sortieralgorithmen. Stellen Sie in einer Tabelle deren Vorteile und Nachteile gegenüber und messen Sie deren
Laufzeit. Was fällt Ihnen auf?
5.6 Diskussionsfragen
•
•
•
Informieren Sie sich zuerst über Algorithmen zur Lösung von linearen
Gleichungssystemen und diskutieren Sie dann in der Gruppe darüber!
Welche Ansätze sind vorteilhafter? Was gilt es zu beachten?
Bilden Sie zwei Gruppen. Diskutieren Sie die Bedeutung des Gebietes
„Algorithmen und Datenstrukturen“ für die Informatik. Eine Gruppe
„verteidigt“ die Position – die andere „attackiert“.
Jeder von Ihnen „übernimmt“ einen Datentyp und präsentiert diesen
der Gruppe. Jeder soll versuchen, „seinen“ Datentyp möglichst positiv
darzustellen. Jemand versucht nun, die Datentypen schlecht zu machen.
5.7 Timeline: Algorithmen und Datenstrukturen
1700 v. Chr. Papyrus Rhind: älteste schriftliche Rechenaufgabe (Ägypten).
300 v. Chr. EUKLID (365–300 v.Chr.) beschreibt einen Algorithmus zur Bestimmung
des größten gemeinsamen Teilers (ggT) in seinem 7. Buch der Elemente.
230 v. Chr. ERATHOSTENES (276–197 v.Chr.) entwickelt einen Algorithmus zur
Berechnung von Primzahlen (Sieb des Erathostenes).
800 MOHAMMED IBN MUSA ABU DJAFAR AL CHORESMI (780–850) beschreibt Vorgehensweisen für Testamentsvollstreckungen. Bildung des Begriffs Algorithmus aus
seinem Namen und dem griechischen „arithmo“ für Zahl.
1574 Sammlung von Algorithmen im Rechenbuch von ADAM RIES (1492–1559).
1614 Nach 30 Jahren Arbeit wird die erste Logarithmentafel erstellt.
1703 Binäres Zahlensystem von LEIBNIZ.
1931 Unvollständigkeitssatz von GÖDEL.
1936 Church'sche These.
1960 HOARE stellt den Bubblesort-Algorithmus vor.
1972 Entwicklung der NP-Vollständigkeit zur Beschreibung algorithmischer Computer-Probleme.
80
IK_1_Datenstrukturen.fm Seite 81 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
5.8 Glossar
Algorithmus Beschreibung eines Informationsverarbeitungsmodells oder Prozessablaufs in einer Form, die von einer Maschine ausgeführt werden kann.
Array (Feldtyp) ist die endliche Aneinanderreihung von Datenelementen gleicher
Art in einem zusammenhängenden Speicherbereich. Zugriff mit Hilfe eines Index.
Anweisung (statement) Bestandteile eines Blocks: Kontrollstruktur, Definition oder
Ausdruck.
Ausdruck (expression) Vorschrift zur Berechnung eines Wertes durch Kombination
von Unterausdrücken mit Operatoren oder Funktionsaufrufen. Liefert einen Wert.
Aufzählungstyp (enumeration type) ist ein Datentyp, dessen Wertebereich vollständig durch die Aufzählung der Einzelelemente beschrieben wird. Durch die Reihenfolge der Aufzählung wird eine Ordnungsrelation definiert.
average case ist eine Betrachtungsweise bei der Komplexitätsanalyse von Algorithmen, die sich am Erwartungswert des Betriebsmittelverbrauchs bei der Ausführung
eines Algorithmus orientiert.
Baum ist eine nichtlineare Datenstruktur, die aus einer Menge von Knoten und aus
einer Menge von diese verbindenden, gerichteten Kanten besteht. Bäume werden
hauptsächlich zur Abbildung hierarchischer Beziehungen innerhalb großer Datenmengen oder zur Modellierung rekursiver Objektstrukturen verwendet.
Benutzerdefinierter Typ (user defined type) Typ, der als Klasse, Aufzählungstyp
oder durch eine Typdeklaration eingeführt wird.
Bezeichner (identifier) Name der sich auf eine Variable, einen Typ oder eine Funktion bezieht.
Block eine Liste von Anweisungen, die den Gültigkeitsbereich aller lokal definierten Bezeichner begrenzt.
binärer Baum ist ein spezieller k-närer Baum (siehe dort), der Ordnung 2. Jeder
Knoten mit Ausnahme der Blätter besitzt höchstens zwei und mindestens einen
Nachfolger. Da jeder k-näre Baum in einen binären Baum durch Anwendung geeigneter Transformationsregeln überführt werden kann, werden hier hauptsächlich
Darstellungsformen und Operationen für binäre Bäume behandelt.
binäre Suche ist eine Art der Suche, bei der ein nach dem Primärschlüssel aufsteigend oder absteigend sortierter Datenbestand sukzessive in zwei Hälften aufgeteilt
wird. Das jeweils mittlere Element der aktuellen Bestandshälfte wird mit dem
Suchschlüssel verglichen, das Ergebnis dieses Vergleichs gibt an, ob in der vom mittleren Element ausgehenden linken oder rechten Bestandshälfte weitergesucht wird.
81
IK_1_Datenstrukturen.fm Seite 82 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
BOOLEAN Aufzählungstyp, dessen Wertebereich ausschließlich aus den Wahrheitswerten FALSE und TRUE besteht.
Bubblesort ist das Sortieren durch Austauschen.
CHAR Datentyp, dessen Wertebereich den im Rechner darstellbaren Zeichenvorrat
umfasst (z.B. ASCII-Code).
DATA Schlüsselwort bei der Formulierung von Algorithmen, das den Beginn des
Datenobjektteils anzeigt.
Datenstruktur ist die einfache bzw. komplexe verschachtelte Anordnung von Datenobjekten.
Datentyp ist eine Zusammenfassung von Datenobjekten gleicher Art und dazugehörigen Operationen zu einer begrifflichen Einheit, die es ermöglicht, Objekte als
Vertreter einer bestimmten Objektmenge zu identifizieren, untereinander zu unterscheiden und Manipulationen für die „Klasse“ von Objekten zu formulieren.
Graph ist eine nichtlineare Datenstruktur aus Knoten und Kanten. Die Kanten eines Graphen können sowohl ungerichtet (ungerichteter Graph) als auch gerichtet
(gerichteter Graph) sein. Bäume können und werden meistens als spezielle gerichtete
Graphen aufgefasst. Im Unterschied zu Bäumen können zwei Knoten eines Graphen auch durch mehrere verschiedene Kantenfolgen verbunden sein.
Hashfunktion
ist eine Funktion, die aus einem Primärschlüssel die (relative)
Adresse berechnet, an der ein Datensatz auf einem direkt adressierbaren Speichermedium abgelegt werden soll. Bei der direkten Adressierung ist die Hashfunktion
umkehrbar eindeutig, d.h., es gibt zu jedem Primärschlüssel genau eine Adresse und
umgekehrt. Bei der indirekten Adressierung können mehrere unterschiedliche Primärschlüssel auf die gleiche Adresse abgebildet werden, es ist daher eine Kollisionsbehandlung erforderlich.
Heapsort ist ein Sortierverfahren, das sich die Effizienzvorteile von Binärbäumen
bei Vergleichs- und Suchoperationen in großen Datenbeständen zu eigen macht. Die
zu sortierende Objektmenge wird in ein Feld (Array) übertragen, das als ein Binärbaum in schichtenweiser Darstellung mit niveauweiser Nummerierung angesehen
wird. Anschließend werden, ausgehend von den Blättern, die Elemente so vertauscht, dass die Wurzel eines jeden Teilbaums, jeweils den Datensatz mit dem größten Schlüssel enthält. Der Heapsort weist ein günstiges Verhalten im worst case auf.
Heterogener zusammengesetzter Typ ist ein zusammengesetzter Datentyp mit
Elementen von möglicherweise unterschiedlichen Typen, z.B. eine Klasse.
Homogener zusammengesetzter Typ ist ein zusammengesetzter Datentyp mit
lauter Elementen vom gleichen Typ, z.B. ein Array.
Invariante ist ein logischer Ausdruck, der immer gültig ist, z.B. eine Schleifeninvariante (bei jedem Schleifendurchlauf gültig) oder Klasseninvariante (vor und nach jedem Methodenaufruf gültig).
82
IK_1_Datenstrukturen.fm Seite 83 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
k-närer Baum ist ein Baum, für den gilt: Von jedem Knoten außer einem Blattknoten gehen maximal k Kanten aus, jeder Knoten besitzt damit höchstens k Söhne. Der
Parameter k heißt auch Ordnung des Baumes. Von einem geordneten k-nären Baum
spricht man, wenn die Knoten in einer bestimmten, eindeutigen Reihenfolge notiert
oder bezeichnet werden (z.B. alfabetisch, Väter vor Söhnen, Söhne vor Brüdern).
Kante ist die gerichtete oder ungerichtete Verbindung zwischen genau zwei Datenobjekten oder Knoten einer nichtlinearen Datenstruktur. Diese Verbindung kann
z.B. hierarchische Beziehungen, Transformationen, die Anwendung von Operatoren
oder Zustandsübergänge zwischen den Knoten zum Ausdruck bringen. Ist ein Knoten k von einem Knoten v aus über eine zusammenhängende Folge von Kanten zu
erreichen, so bezeichnet man den Knoten v auch als (ggf. mittelbaren) Vorgänger
von Knoten k und umgekehrt Knoten k als (ggf. mittelbaren) Nachfolger von Knoten v. In Bäumen stellen Kanten gerichtete Vater-Sohn-Beziehungen dar.
Knoten sind Elemente eines Graphen oder Baumes, die aus Datenobjekten beliebiger Komplexität zusammengesetzt sein können. Die in einzelnen Knoten oder in
mehreren durch Kanten verbundenen Knoten abgelegte Information beschreibt
Prozesse, Sachverhalte oder (hierarchische) Zusammenhänge aus der realen Welt.
Kontrollstruktur ist ein schachtelbares Sprachmittel zum Modifizieren der normalen, linearen Abwicklung von Anweisungen (z.B. Verzweigungen, Schleifen usw.).
Implementierung ist die Übersetzung der erarbeiteten Datenmodelle und Datenverarbeitungsprozesse in eine von einem Computer ausführbare Form und deren
Einbindung in die bereits bestehende Informationsstruktur.
INTEGER ist ein Standarddatentyp, der den computerintern darstellbaren Ausschnitt aus der Menge der ganzen Zahlen angibt.
Komplexität von Algorithmen beschreibt Speicherplatzbedarf und die Laufzeit in
Abhängigkeit von der eingegebenen Problemgröße n. Da das Verhalten des Algorithmus bei wachsender Problemgröße n meist nicht präzise angegeben werden
kann, wird versucht, das Wachstumsverhalten auf eine bekannte Funktion g(n) zurückzuführen. Die so genannte O-Notation f(n) = O(g(n)) bringt zum Ausdruck,
dass durch g(n) eine obere Grenze für die Anzahl der nötigen Elementaroperationen
f(n) bei wachsender Problemgröße angegeben wird.
Notation von Algorithmen ist die Darstellung von Algorithmen in verbaler, quasiformaler oder grafischer Form. Gebräuchliche Notationsformen sind Pseudocode,
Struktogramme und Flussdiagramme. Nach BÖHM und JACOPINI gibt es für jeden
Algorithmus eine äquivalente Darstellung, die mit den Strukturblöcken Sequenz,
Wiederholung und Verzweigung auskommt.
Nachfolger heißt ein Knoten n, wenn dieser von einem Knoten k aus über eine
zusammenhängende Folge von q Kanten zu erreichen ist, falls q = 1. Er wird als mittelbarer Nachfolger von k bezeichnet, falls q > 1 ist. Die Nachfolger eines Knotens
werden auch als Söhne dieses Knoten bezeichnet.
83
IK_1_Datenstrukturen.fm Seite 84 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
Notation ist eine bestimmte Darstellungsform von Information durch Symbole, wie
zum Beispiel zum Aufzeichnen von Noten, von Schachpartien oder von mathematischen Modellen. Die Notation einer Programmiersprache bestimmt die zulässigen
Sprachelemente, wie z.B.: Konstante, Ausdrücke und Anweisungen und teilweise die
Syntax.
Quicksort Sortierverfahren, das auf den Prinzipien Austauschen und Zerlegen beruht.
Rekursion ist die Definition einer Datenstruktur, eines Verfahrens (Algorithmus)
oder einer (mathematischen) Funktion durch sich selbst. Eine rekursive Verfahrensvorschrift besteht in der Regel aus einer Terminationsbedingung, einer optionalen
Ausführungsanweisung und einem Selbstaufruf. Die wohl bekannteste rekursiv formulierte Funktion ist folgende Vorschrift zur Fakultätsberechnung: n! = n ((n – 1)!)
mit der Terminationsbedingung 0! = 1.
Sortieren ist die Umordnung einer Menge von Objekten oder Datensätzen so, dass
die Objekte entsprechend einer Ordnungsrelation (numerisch, lexikografisch) aufoder absteigend angeordnet sind. Befindet sich der zu sortierende Datenbestand zum
Zeitpunkt des Umordnens vollständig im Hauptspeicher, so spricht man von einem
internen Sortierverfahren, andernfalls von einem externen Sortierverfahren.
Suche ist das Auffinden eines oder aller Datenobjekte in einem Datenbestand, die
ein bestimmtes Suchkriterium erfüllen. Die Effizienz der Suche wird von der Art des
Suchkriteriums (einfacher oder zusammengesetzter Schlüssel), dem benutzten Suchverfahren und von der Organisation des Datenbestandes bestimmt.
Suchbaum ist eine nichtlineare Datenstruktur, in der durch Schlüssel identifizierte
Datenobjekte auf effiziente Weise ordnungserhaltend eingefügt und gefunden werden
können. Über die Menge aller vorhandenen Schlüssel muss eine lineare Ordnungsrelation (größer, gleich oder kleiner) definiert sein. Suchbäume werden meist als Binärbäume
dargestellt, in denen jeder Knoten einen einzigen Schlüsseleintrag s enthält. Bei der
Suche nach einem eindeutigen Schlüssel x wird in jedem Knoten des Suchbaumes
zum linken Nachfolger verzweigt, wenn x kleiner ist als der Schlüsseleintrag s im aktuell betrachteten Knoten, und nach rechts verzweigt, wenn x größer ist als s. Die
Komplexität der Schlüsselvergleiche ist damit durch O(ld n) gegeben. Um die Sortierfolge aller Datenobjekte zu erhalten, ist der Suchbaum lediglich in symmetrischer
Ordnung zu traversieren (inorder).
Traversieren von Bäumen: Da man bei den gebräuchlichen Darstellungs- und Speicherungsformen für Bäume auf einzelne Knoten nur indirekt, von der Wurzel aus,
zugreifen kann, ist es nötig, einen Baum in einer bestimmten Reihenfolge so zu
durchlaufen, dass jeder Knoten genau einmal aufgesucht und ausgewertet wird. Normalerweise werden drei verschiedene Vorgehensweisen für das Durchlaufen eines
Binärbaumes in Betracht gezogen: das Traversieren in Präordnung, in Postordung
und in symmetrischer Ordnung. Allen Vorgehensweisen ist gemeinsam, dass der Binärbaum in jedem Knoten k in drei Elemente aufgeteilt wird: den von k ausgehenden
rechten Teilbaum, die Wurzel k und den von k ausgehenden linken Teilbaum. Damit
lassen sich Traversierungsalgorithmen relativ leicht rekursiv formulieren, indem die
Reihenfolge des Abarbeitens der genannten drei Elemente festgelegt wird.
84
IK_1_Datenstrukturen.fm Seite 85 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
REAL ist ein Datentyp, der die im Rechner darstellbare Teilmenge der reellen Zahlen angibt.
Record (Verbund, Satz) ist die Zusammenfassung von mehreren, auch unterschiedlichen Datentypen zu einem neuen Datentyp. Die einzelnen Komponenten des Verbunds können mit Hilfe der Punktqualifizierung angesprochen werden (z.B.
person.name).
Schlange (engl. queue) ist eine lineare Datenstruktur, mit der eine Folge von Datenobjekten eines bestimmten Datentyps nach dem „first-in-first-out“-Prinzip verwaltet
wird. Neu hinzu kommende Elemente werden stets am Ende der Folge angefügt
(Operation append). Entfernt werden Elemente ausschließlich am Anfang der Folge
(Operation remove). Die Schlange lässt sich wie der Stapel als sequentielle oder als
verkettete Liste organisieren.
Set oder Mengentyp ist ein Datentyp, der eine Menge von Objekten im Sinne der
Mengenlehre nachbildet. Die Elemente der Menge gehören alle einem einfachen ordinalen Datentyp an.
Stack (Stapel) ist eine lineare Datenstruktur, bei der eine Folge von Datenobjekten
eines bestimmten Datentyps nach dem „last-in-first-out“-Prinzip verwaltet wird. Für
den Stapel gibt es in der Regel zwei grundlegende Operationen: Die Operation push
fügt neu hinzukommende Elemente stets am Ende der Folge an, die Operation pop
liefert das letzte in die Folge aufgenommene Element. Stapel können als sequentielle
Liste (statisches Feld) oder als verkettete Liste realisiert werden.
Standardtypen sind elementare Datentypen, die in den meisten (höheren) Programmiersprachen zur Verfügung gestellt werden. Hierzu gehören die Datentypen INTEGER, REAL, CHAR und BOOLEAN.
Typ (type) Interpretation eines Bitmusters als Wert. Festlegung erlaubter Operationen und der Auswirkungen dieser Operationen auf die Werte, d.h. Exemplare des
Typs.
Typdeklaration (typedef) Neuer Bezeichner für einen anderen einfachen oder zusammengesetzten Typ.
Verkettete Liste ist eine Folge von Datenobjekten eines bestimmten Datentyps, bei
der jedes Datenobjekt aus einem Datenteil und einem Verweisteil besteht. Da im Gegensatz zur sequentiellen Liste die physikalische Aufeinanderfolge der Elemente
nicht mit der logischen Reihenfolge, die der zugrundegelegten Ordnungsrelation entspricht, übereinstimmt, ist eine Verzeigerung der Datenobjekte einzurichten: Ein zusätzliches, als Anker bezeichnetes Datenobjekt, verweist auf das erste Listenelement.
In diesem sowie in jedem weiteren Element wird ein Verweis auf das Nachfolgerelement festgehalten. Der Zeiger des letzten Elements markiert das Ende der Liste
(NIL). Werden in jedem Listenelement mehrere Verweise gepflegt, spricht man von
doppelt oder mehrfach verketteten Listen.
85
IK_1_Datenstrukturen.fm Seite 86 Montag, 30. Dezember 2002 10:35 10
IK 1 Algorithmen & Datenstrukturen
Zeichenkette (String) ist eine Zusammenhängende Folge von Zeichen aus einem
endlichen Zeichenvorrat, die ein Phänomen der realen Welt repräsentiert. Im Rechner werden Zeichenketten in einem Array abgelegt; das Ende einer Zeichenkette
wird in der Regel durch ein Sonderzeichen bestimmt.
Zeigertyp ist ein Datentyp, der einen Verweis (Zeiger, auf der Rechnerebene Adresse) auf ein Datenobjekt eines zugrunde gelegten Datentyps beschreibt. Der Wertebereich des Zeigers umfasst hierbei die möglichen Speicheradressen und den Wert
NIL. Ein Zeiger mit dem Wert NIL verweist auf kein Datenobjekt.
Zusammengesetzter Typ („compound type“) Typ, der aus Elementen zusammengesetzt ist. Gegenteil von primitivem Typ.
Vorgänger eines Knotens: Ist ein Knoten k von einem Knoten v aus über eine zusammenhängende Folge von q Kanten zu erreichen, so bezeichnet man den Knoten
v als Vorgänger des Knotens k, falls q = 1, und als mittelbaren Vorgänger von k, falls
q > 1. Ein Vorgänger eines Knotens k wird auch als Vater von k bezeichnet.
Wurzel ist ein Datenobjekt oder Element eines Teilbaumes, zu dem kein Vorgänger
existiert. Von der Wurzel des Baumes aus können alle Knoten eines Baumes auf genau einem Weg (d.h. einer zusammenhängenden endlichen Folge gerichteter Kanten) erreicht werden.
86
Herunterladen