11 Listen, Stapel, Warteschlangen - uni-bremen.deroefer/pi1/11.pdf · Eine Warteschlange dient zum...

23
Universität Bremen Listen, Stapel, Warteschlangen Thomas Röfer Abstrakte Datentypen Reihung Stapel Warteschlange Einfach und doppelt verkettete Liste

Transcript of 11 Listen, Stapel, Warteschlangen - uni-bremen.deroefer/pi1/11.pdf · Eine Warteschlange dient zum...

Page 1: 11 Listen, Stapel, Warteschlangen - uni-bremen.deroefer/pi1/11.pdf · Eine Warteschlange dient zum Zwischenspeichern von Elementen Der Zugriff erfolgt nach dem first-in , first-out

Universität Bremen

Listen, Stapel, Warteschlangen

Thomas Röfer

Abstrakte Datentypen

Reihung

Stapel

Warteschlange

Einfach und doppelt verkettete Liste

Page 2: 11 Listen, Stapel, Warteschlangen - uni-bremen.deroefer/pi1/11.pdf · Eine Warteschlange dient zum Zwischenspeichern von Elementen Der Zugriff erfolgt nach dem first-in , first-out

PI-1: Listen, Stapel, Warteschlangen 2

Universität Bremen

Rückblick „Prozeduren, Funktionen, Datenströme, JavaDoc“

Unterprogramme

streamFileInputStream

streamFileInputStream

readerInputStreamReader

readerInputStreamReader

bufferBufferedReader

bufferBufferedReader

lineString

lineString

Hallo 21333 "dies und das"

String[ ] argsString[] args

"Hallo"args[0]

args.length

args[1]

args[2] "dies und das"

"21333"

3String[ ] argsString[] args

"Hallo"args[0]

args.length

args[1]

args[2] "dies und das"

"21333"

3

>java Klasse

Ein/Ausgabe & Transiente P.

Formale ↔ Aktuelle Parameter

Kopf (Signatur) ↔ Rumpf

Prozeduren ↔ Funktionenplus : int × long � intplus : int × long � longplus : long × long � longplus : long × int � int

plus : int × long � intplus : int × long � longplus : long × long � longplus : long × int � int

Überladung Die Funktion main()

JavaDoc Datenströme Datenströme in Java

Page 3: 11 Listen, Stapel, Warteschlangen - uni-bremen.deroefer/pi1/11.pdf · Eine Warteschlange dient zum Zwischenspeichern von Elementen Der Zugriff erfolgt nach dem first-in , first-out

PI-1: Listen, Stapel, Warteschlangen 3

Universität Bremen

Abstrakte Datentypen

� Definition

� Ein abstrakter Datentyp besteht aus den Daten selbst (z.B. Objektzustand) und den auf den Daten auszuführenden Operationen (z.B. Methoden)

� Öffentliche Schnittstelle der Operationen� Interne Abläufe werden versteckt (Geheimnisprinzip)� In Java: Klassen

� Algebraische abstrakte Datentypen

� Neben der Schnittstelle der Operationen wird zusätzlich die Semantik der Operationen formal beschrieben, z.B. in Form von Axiomen� plus : int × int � int

� null : � int

� plus(a, b) = plus(b, a)

� plus(a, null) = a

� plus(a, plus(b, c)) = plus(plus(a, b), c)

Page 4: 11 Listen, Stapel, Warteschlangen - uni-bremen.deroefer/pi1/11.pdf · Eine Warteschlange dient zum Zwischenspeichern von Elementen Der Zugriff erfolgt nach dem first-in , first-out

PI-1: Listen, Stapel, Warteschlangen 4

Universität Bremen

Reihungen

� Eigenschaften

� Wahlfreier Zugriff auf alle Elemente in konstanter Zeit über Index� Reihungen haben normalerweise eine feste Größe� Wenn nicht, sind Vergrößern und Verkleinern teure Operationen (neue Reihung anlegen,

alte Daten hinüberkopieren)� Einfügen und Löschen sind teure Operationen, da alle Elemente hinter dem

eingefügten/gelöschten kopiert werden müssen

� Operationen einer Reihung fester Größe

� Reihung erzeugen� create : int � Array

� Eintrag schreiben� set : Array × int × Entry � Array

� Eintrag auslesen� get : Array × int � Entry

� Länge auslesen� length : Array � int

Page 5: 11 Listen, Stapel, Warteschlangen - uni-bremen.deroefer/pi1/11.pdf · Eine Warteschlange dient zum Zwischenspeichern von Elementen Der Zugriff erfolgt nach dem first-in , first-out

PI-1: Listen, Stapel, Warteschlangen 5

Universität Bremen

Reihung mit Einfügen und Löschen

// int = Datentyp der Einträge

class Array

{

int[] entries = new int[0];

int get(int pos)

{

return entries[pos];

}

void set(int pos, int entry)

{

entries[pos] = entry;

}

boolean empty()

{

return entries.length == 0;

}

// int = Datentyp der Einträge

class Array

{

int[] entries = new int[0];

int get(int pos)

{

return entries[pos];

}

void set(int pos, int entry)

{

entries[pos] = entry;

}

boolean empty()

{

return entries.length == 0;

}

void insertBefore(int pos, int entry)

{

int[] temp = new int[entries.length + 1];

for(int i = 0; i < pos; ++i)

temp[i] = entries[i];

temp[pos] = entry;

for(int i = pos; i < entries.length; ++i)

temp[i + 1] = entries[i];

entries = temp;

}

void remove(int pos)

{

int[] temp = new int[entries.length - 1];

for(int i = 0; i < pos; ++i)

temp[i] = entries[i];

for(int i = pos + 1; i < entries.length; ++i)

temp[i - 1] = entries[i];

entries = temp;

}

}

void insertBefore(int pos, int entry)

{

int[] temp = new int[entries.length + 1];

for(int i = 0; i < pos; ++i)

temp[i] = entries[i];

temp[pos] = entry;

for(int i = pos; i < entries.length; ++i)

temp[i + 1] = entries[i];

entries = temp;

}

void remove(int pos)

{

int[] temp = new int[entries.length - 1];

for(int i = 0; i < pos; ++i)

temp[i] = entries[i];

for(int i = pos + 1; i < entries.length; ++i)

temp[i - 1] = entries[i];

entries = temp;

}

}

Page 6: 11 Listen, Stapel, Warteschlangen - uni-bremen.deroefer/pi1/11.pdf · Eine Warteschlange dient zum Zwischenspeichern von Elementen Der Zugriff erfolgt nach dem first-in , first-out

PI-1: Listen, Stapel, Warteschlangen 6

Universität Bremen

Stapel (Stack)

� Zweck

� Ein Stapel dient zum Zwischenspeichern von Elementen

� Der Zugriff erfolgt nach dem last-in, first-out Prinzip (lifo), d.h. das zuletzt abgelegte Element wird zuerst zurückgeliefert

� Operationen

� Stapel erzeugen� create : � Stack

� Eintrag ablegen� push : Stack × Entry � Stack

� Kopf auslesen� top : Stack � Entry

� Eintrag entnehmen� pop : Stack � Stack

� Auf Leere testen� empty : Stack � boolean

� Axiome

� top(push(s, e)) = e

� pop(push(s, e)) = s

� empty(create())

� ¬ empty(push(s, e))

� Alternative

� Eintrag entnehmen und zurückliefern� pop : Stack � Stack × Entry

Page 7: 11 Listen, Stapel, Warteschlangen - uni-bremen.deroefer/pi1/11.pdf · Eine Warteschlange dient zum Zwischenspeichern von Elementen Der Zugriff erfolgt nach dem first-in , first-out

PI-1: Listen, Stapel, Warteschlangen 7

Universität Bremen

Beispiel: Ein UPN-Rechner

� Umgekehrte Polnische Notation

� Die Operanden kommen zuerst, dann kommt der Operator, z.B. 1 2 +

� Arbeitet als Stack-Maschine: Jeder Operator holt sich seine Operanden von der Spitze des Stapels und legt das Ergebnis wieder dort ab

� Beispiel

� Für 1 + 2 * 3 schreibt man: 1 2 3 * +

77+

11

66*

11

22

333

11

222

111

Page 8: 11 Listen, Stapel, Warteschlangen - uni-bremen.deroefer/pi1/11.pdf · Eine Warteschlange dient zum Zwischenspeichern von Elementen Der Zugriff erfolgt nach dem first-in , first-out

PI-1: Listen, Stapel, Warteschlangen 8

Universität Bremen

Beispiel: Ein UPN-Rechner in Java

class Eval

{

static double eval(String[] expression)

{

Stack stack = new Stack();

for(int i = 0; i < expression.length; ++i)

{

String s = expression[i];

if(s.equals("+"))

stack.push(stack.pop() + stack.pop());

else if(s.equals("-"))

stack.push(-stack.pop() + stack.pop());

else if(s.equals("*"))

stack.push(stack.pop() * stack.pop());

else if(s.equals("/"))

stack.push(1 / stack.pop() * stack.pop());

else

stack.push(Double.parseDouble(s));

}

return stack.pop();

}

}

class Eval

{

static double eval(String[] expression)

{

Stack stack = new Stack();

for(int i = 0; i < expression.length; ++i)

{

String s = expression[i];

if(s.equals("+"))

stack.push(stack.pop() + stack.pop());

else if(s.equals("-"))

stack.push(-stack.pop() + stack.pop());

else if(s.equals("*"))

stack.push(stack.pop() * stack.pop());

else if(s.equals("/"))

stack.push(1 / stack.pop() * stack.pop());

else

stack.push(Double.parseDouble(s));

}

return stack.pop();

}

}

Page 9: 11 Listen, Stapel, Warteschlangen - uni-bremen.deroefer/pi1/11.pdf · Eine Warteschlange dient zum Zwischenspeichern von Elementen Der Zugriff erfolgt nach dem first-in , first-out

PI-1: Listen, Stapel, Warteschlangen 9

Universität Bremen

StackStack

toptop 334

Beschränkter Stapel

00000003517entries

s.push(6)

s.pop()

6

Page 10: 11 Listen, Stapel, Warteschlangen - uni-bremen.deroefer/pi1/11.pdf · Eine Warteschlange dient zum Zwischenspeichern von Elementen Der Zugriff erfolgt nach dem first-in , first-out

PI-1: Listen, Stapel, Warteschlangen 10

Universität Bremen

Beschränkter Stapel

class Stack

{

double[] entries;

int top;

Stack(int size)

{

entries = new double[size];

top = 0;

}

void push(double entry)

{

assert top < entries.length;

entries[top++] = entry;

}

class Stack

{

double[] entries;

int top;

Stack(int size)

{

entries = new double[size];

top = 0;

}

void push(double entry)

{

assert top < entries.length;

entries[top++] = entry;

}

double pop()

{

assert !empty();

return entries[--top];

}

boolean empty()

{

return top == 0;

}

}

// double = Datentyp der Einträge

double pop()

{

assert !empty();

return entries[--top];

}

boolean empty()

{

return top == 0;

}

}

// double = Datentyp der Einträge

Page 11: 11 Listen, Stapel, Warteschlangen - uni-bremen.deroefer/pi1/11.pdf · Eine Warteschlange dient zum Zwischenspeichern von Elementen Der Zugriff erfolgt nach dem first-in , first-out

PI-1: Listen, Stapel, Warteschlangen 11

Universität Bremen

Stack als einfach verkettete Liste

StackElementStackElement

valuevalue 11

nextnext

StackElementStackElement

valuevalue 22

nextnext

StackElementStackElement

valuevalue 33

nextnext

StackStack

firstfirst

StackElementStackElement

valuevalue 44

nextnext

s.push(4)

s.pop()

Page 12: 11 Listen, Stapel, Warteschlangen - uni-bremen.deroefer/pi1/11.pdf · Eine Warteschlange dient zum Zwischenspeichern von Elementen Der Zugriff erfolgt nach dem first-in , first-out

PI-1: Listen, Stapel, Warteschlangen 12

Universität Bremen

Stack als einfach verkettete Liste

class Stack

{

StackElement first;

Stack()

{

first = null;

}

void push(double entry)

{

StackElement s =

new StackElement();

s.value = entry;

s.next = first;

first = s;

}

class Stack

{

StackElement first;

Stack()

{

first = null;

}

void push(double entry)

{

StackElement s =

new StackElement();

s.value = entry;

s.next = first;

first = s;

}

double pop()

{

double d = first.value;

first = first.next;

return d;

}

boolean empty()

{

return first == null;

}

}

double pop()

{

double d = first.value;

first = first.next;

return d;

}

boolean empty()

{

return first == null;

}

}

class StackElement

{

StackElement next;

double value;

}

class StackElement

{

StackElement next;

double value;

}

Page 13: 11 Listen, Stapel, Warteschlangen - uni-bremen.deroefer/pi1/11.pdf · Eine Warteschlange dient zum Zwischenspeichern von Elementen Der Zugriff erfolgt nach dem first-in , first-out

PI-1: Listen, Stapel, Warteschlangen 13

Universität Bremen

Warteschlange (Queue)

� Zweck

� Eine Warteschlange dient zum Zwischenspeichern von Elementen

� Der Zugriff erfolgt nach dem first-in, first-out Prinzip (lilo), d.h. das zuerst abgelegte Element wird auch zuerst zurückgeliefert

� Operationen

� Warteschlange erzeugen� create : � Queue

� Eintrag ablegen� push : Queue × Entry � Queue

� Kopf auslesen� top : Queue � Entry

� Eintrag entnehmen� pop : Queue � Queue

� Auf Leere testen� empty : Queue � boolean

� Axiome

� top(push(push(create(), e) , f)) = e

� pop(push(push(create(), e) , f)) =

push(create(), f)

� empty(create())

� ¬ empty(push(q, e))

� Alternative

� Eintrag entnehmen und zurückliefern� pop : Queue � Queue × Entry

Page 14: 11 Listen, Stapel, Warteschlangen - uni-bremen.deroefer/pi1/11.pdf · Eine Warteschlange dient zum Zwischenspeichern von Elementen Der Zugriff erfolgt nach dem first-in , first-out

PI-1: Listen, Stapel, Warteschlangen 14

Universität Bremen

Beispiel: UPN-Rechner mit Pufferclass Eval

{

static double eval(String expression)

{

return eval(split(expression));

}

static Queue split(String expression)

{

Queue queue = new Queue();

expression = expression.trim();

while(!expression.equals(""))

{

int index = (expression + " ").indexOf(" ");

queue.push(expression.substring(0, index));

expression = expression.substring(index).trim();

}

return queue;

}

static double eval(Queue queue)

{

Stack stack = new Stack(10);

while(!queue.empty())

{

String s = queue.pop();

class Eval

{

static double eval(String expression)

{

return eval(split(expression));

}

static Queue split(String expression)

{

Queue queue = new Queue();

expression = expression.trim();

while(!expression.equals(""))

{

int index = (expression + " ").indexOf(" ");

queue.push(expression.substring(0, index));

expression = expression.substring(index).trim();

}

return queue;

}

static double eval(Queue queue)

{

Stack stack = new Stack(10);

while(!queue.empty())

{

String s = queue.pop();

Page 15: 11 Listen, Stapel, Warteschlangen - uni-bremen.deroefer/pi1/11.pdf · Eine Warteschlange dient zum Zwischenspeichern von Elementen Der Zugriff erfolgt nach dem first-in , first-out

PI-1: Listen, Stapel, Warteschlangen 15

Universität Bremen

QueueQueue

firstfirst 22

lastlast 990

Beschränke Warteschlange (Ringpuffer)

null"11""19""42""8""7""0""3""5""17"entries

q.push("6")

q.pop()

"6"

3

Page 16: 11 Listen, Stapel, Warteschlangen - uni-bremen.deroefer/pi1/11.pdf · Eine Warteschlange dient zum Zwischenspeichern von Elementen Der Zugriff erfolgt nach dem first-in , first-out

PI-1: Listen, Stapel, Warteschlangen 16

Universität Bremen

Beschränke Warteschlange (Ringpuffer)

class Queue

{

String[] entries;

int first,

last;

Queue(int size)

{

entries = new String[size + 1];

first = last = 0;

}

void push(String entry)

{

entries[last++] = entry;

last %= entries.length;

assert !empty();

}

class Queue

{

String[] entries;

int first,

last;

Queue(int size)

{

entries = new String[size + 1];

first = last = 0;

}

void push(String entry)

{

entries[last++] = entry;

last %= entries.length;

assert !empty();

}

String pop()

{

assert !empty();

String entry = entries[first++];

first %= entries.length;

return entry;

}

boolean empty()

{

return first == last;

}

}

// String = Datentyp der Einträge

String pop()

{

assert !empty();

String entry = entries[first++];

first %= entries.length;

return entry;

}

boolean empty()

{

return first == last;

}

}

// String = Datentyp der Einträge

Page 17: 11 Listen, Stapel, Warteschlangen - uni-bremen.deroefer/pi1/11.pdf · Eine Warteschlange dient zum Zwischenspeichern von Elementen Der Zugriff erfolgt nach dem first-in , first-out

PI-1: Listen, Stapel, Warteschlangen 17

Universität Bremen

Warteschlange als einfach verkettete Liste

QueueElementQueueElement

valuevalue "1""1"

nextnext

QueueElementQueueElement

valuevalue "2""2"

nextnext

QueueElementQueueElement

valuevalue "3""3"

nextnext

QueueQueue

firstfirst

lastlast

QueueElementQueueElement

valuevalue "4""4"

nextnext

q.push(4)

q.pop()

Page 18: 11 Listen, Stapel, Warteschlangen - uni-bremen.deroefer/pi1/11.pdf · Eine Warteschlange dient zum Zwischenspeichern von Elementen Der Zugriff erfolgt nach dem first-in , first-out

PI-1: Listen, Stapel, Warteschlangen 18

Universität Bremen

Warteschlange als einfach verkettete Liste

class QueueElement

{

QueueElement next;

String value;

QueueElement(String s)

{

value = s;

next = null;

}

}

class Queue

{

QueueElement first,

last;

Queue()

{

first = last = null;

}

class QueueElement

{

QueueElement next;

String value;

QueueElement(String s)

{

value = s;

next = null;

}

}

class Queue

{

QueueElement first,

last;

Queue()

{

first = last = null;

}

void push(String s)

{

if(empty())

first = last = new QueueElement(s);

else

{

last.next = new QueueElement(s);

last = last.next;

}

}

String pop()

{

assert !empty();

String s = first.value;

first = first.next;

return s;

}

boolean empty()

{

return first == null;

}

}

void push(String s)

{

if(empty())

first = last = new QueueElement(s);

else

{

last.next = new QueueElement(s);

last = last.next;

}

}

String pop()

{

assert !empty();

String s = first.value;

first = first.next;

return s;

}

boolean empty()

{

return first == null;

}

}

Page 19: 11 Listen, Stapel, Warteschlangen - uni-bremen.deroefer/pi1/11.pdf · Eine Warteschlange dient zum Zwischenspeichern von Elementen Der Zugriff erfolgt nach dem first-in , first-out

PI-1: Listen, Stapel, Warteschlangen 19

Universität Bremen

Listen

� Einfach verkettete Liste

� Jedes Element enthält einen Zeiger auf seinen Nachfolger� Kann nur in einer Richtung durchlaufen werden� Einfügen immer hinter ein existierendes Listenelement� Ein Element kann nur gelöscht werden, wenn sein Vorgänger

bekannt ist

� Doppelt verkettete Liste

� Jedes Element enthält einen Zeiger auf seinen Vorgänger und seinen Nachfolger

� Kann vor- und rückwärts durchlaufen werden� Einfügen vor und hinter existierende Listenelemente� Elemente können problemlos gelöscht werden

ListElementListElement

valuevalue 11

nextnext

ListElementListElement

valuevalue 22

nextnext

ListElementListElement

valuevalue 33

nextnext nullnullListList

firstfirst

DLListElementDLListElement

valuevalue 11

previousprevious nullnull

nextnext

DLListElementDLListElement

valuevalue 11

previousprevious

nextnext

DLListElementDLListElement

valuevalue 11

previousprevious

nextnext nullnull

DLListDLList

firstfirst

lastlast

Page 20: 11 Listen, Stapel, Warteschlangen - uni-bremen.deroefer/pi1/11.pdf · Eine Warteschlange dient zum Zwischenspeichern von Elementen Der Zugriff erfolgt nach dem first-in , first-out

PI-1: Listen, Stapel, Warteschlangen 20

Universität Bremen

Operationen auf Listen

� Eigenschaften

� Zugriff auf Elemente nur in fester Reihenfolge

� Einfügen und Löschen sind in konstanter Zeit möglich

� Speicherplatzverbrauch höher als bei Reihungen

� Operationen auf Listen (z.B. einfach verkettet)

� List� create : � List

� first : List � ListElement

� insert : List × Entry × ListElement � List

� remove : List × ListElement � List

� empty : List � boolean

� ListElement� last : ListElement � boolean

� next : ListElement � ListElement

� entry : ListElement � Entry

Page 21: 11 Listen, Stapel, Warteschlangen - uni-bremen.deroefer/pi1/11.pdf · Eine Warteschlange dient zum Zwischenspeichern von Elementen Der Zugriff erfolgt nach dem first-in , first-out

PI-1: Listen, Stapel, Warteschlangen 21

Universität Bremen

Einfach verkettete Liste mit Index

class ListElement

{

int entry;

ListElement next;

ListElement(int e)

{

entry = e;

next = null;

}

}

class List

{

ListElement first;

List()

{

first = null;

}

class ListElement

{

int entry;

ListElement next;

ListElement(int e)

{

entry = e;

next = null;

}

}

class List

{

ListElement first;

List()

{

first = null;

}

ListElement at(int pos)

{

ListElement current = first;

while(pos > 0 && current != null)

{

current = current.next;

--pos;

}

return current;

}

int get(int pos)

{

return at(pos).entry;

}

void set(int pos, int entry)

{

at(pos).entry = entry;

}

ListElement at(int pos)

{

ListElement current = first;

while(pos > 0 && current != null)

{

current = current.next;

--pos;

}

return current;

}

int get(int pos)

{

return at(pos).entry;

}

void set(int pos, int entry)

{

at(pos).entry = entry;

}

Page 22: 11 Listen, Stapel, Warteschlangen - uni-bremen.deroefer/pi1/11.pdf · Eine Warteschlange dient zum Zwischenspeichern von Elementen Der Zugriff erfolgt nach dem first-in , first-out

PI-1: Listen, Stapel, Warteschlangen 22

Universität Bremen

Einfach verkettete Liste mit Index

void remove(int pos)

{

if(pos == 0)

first = first.next;

else

{

ListElement current = at(pos - 1);

current.next = current.next.next;

}

}

boolean empty()

{

return first == null;

}

}

void remove(int pos)

{

if(pos == 0)

first = first.next;

else

{

ListElement current = at(pos - 1);

current.next = current.next.next;

}

}

boolean empty()

{

return first == null;

}

}

void insertBefore(int pos, int entry)

{

ListElement newElem =

new ListElement(entry);

if(pos == 0)

{

newElem.next = first;

first = newElem;

}

else

{

ListElement current = at(pos - 1);

newElem.next = current.next;

current.next = newElem;

}

}

void insertBefore(int pos, int entry)

{

ListElement newElem =

new ListElement(entry);

if(pos == 0)

{

newElem.next = first;

first = newElem;

}

else

{

ListElement current = at(pos - 1);

newElem.next = current.next;

current.next = newElem;

}

}

Page 23: 11 Listen, Stapel, Warteschlangen - uni-bremen.deroefer/pi1/11.pdf · Eine Warteschlange dient zum Zwischenspeichern von Elementen Der Zugriff erfolgt nach dem first-in , first-out

PI-1: Listen, Stapel, Warteschlangen 23

Universität Bremen

Abbildung von Stack/Queue auf List

class Stack

{

List list = new List();

void push(Entry e)

{

list.insertBefore(e, list.first());

}

Entry pop()

{

ListElement e = first();

list.remove(e);

return e.entry;

}

boolean empty()

{return list.empty();}

class Stack

{

List list = new List();

void push(Entry e)

{

list.insertBefore(e, list.first());

}

Entry pop()

{

ListElement e = first();

list.remove(e);

return e.entry;

}

boolean empty()

{return list.empty();}

class Queue

{

List list = new List();

void push(Entry e)

{

list.insertBefore(e, list.first());

}

Entry pop()

{

ListElement e = last();

list.remove(e);

return e.entry;

}

boolean empty()

{return list.empty();}

class Queue

{

List list = new List();

void push(Entry e)

{

list.insertBefore(e, list.first());

}

Entry pop()

{

ListElement e = last();

list.remove(e);

return e.entry;

}

boolean empty()

{return list.empty();}