Föreläsning 11
ADT:er och datastrukturer
ADT:er och datastrukturer
• Dessa två begrepp är kopplade till varandra men de
står för olika saker.
• En ADT (abstrakt datatyp) är just abstrakt och är
inte kopplad till något programmeringsspråk eller till
implementering.
• En datastruktur är konkret och till de flesta
programmeringsspråk finns en eller flera inbyggda
datastrukturer.
2
ADT (abstrakt datatyp)
• En ADT är en programspråksoberoende beskrivning
av en mängd data och operationer på denna data för
att lagra, komma åt och manipulera den.
• I objektorienterade programmeringsspråk (som
Java) implementeras ADT:er med klasser.
• Med hjälp av gränssnitt kan man säkerställa att man
får med alla de metoder som anges i ADT:n.
• Exempel på vanliga abstrakta datatyper är:
- mängd
- sekvens (lista, kö, stack)
3
ADT:n Mängd
• Exempel på egenskaper:
- En oordnad samling av unika element.
- Kan innehålla ett obegränsat antal element.
• Exempel på operationer:
Beskrivning: Skapar en tom mängd.
Pre: sant
Post: en ny tom mängd har skapats
Mängd()
Beskrivning: Kollar om ett element finns
i mängden.
Pre: sant
Post: resultat = sant om elementet i
mängden, annars falskt
contains(in: element, ut: boolskt värde)
Beskrivning: Lägger till ett element i
mängden.
Pre: !contains(element)
Post: element är lagt till mängden
add(in: element)
Beskrivning: Tar bort ett element ur
mängden.
Pre: contains(element)
Post: element är borttaget ur mängden
remove(in: element)
Beskrivning: Kollar om mängden är tom.
Pre: sant
Post: resultat = sant om mängden är tom,
annars falskt
isEmpty(ut: boolskt värde)
Beskrivning: Bestämmer mängdens storlek.
Pre: sant
Post: resultat = mängdens storlek
size(ut: heltal)
4
Gränssnitt
• De operationer som finns till en ADT kan samlas
i ett gränssnitt som en implementering av ADT:n
kan implementera.
• Exempel på Javagränssnitt för ADT:n Mängd:
public interface SetADT<E> {
public boolean contains(E element);
public void add(E element);
public void remove(E element);
public boolean isEmpty();
public int size();
}
5
ADT:n Lista
• Exempel på egenskaper:
- En ordnad sekvens av element.
- Kan innehålla ett obegränsat antal element.
• Exempel på operationer:
Beskrivning: Skapar en tom lista.
Pre: sant
Post: en ny tom lista har skapats
Lista()
Beskrivning: Tar bort ett element på en
viss plats ur listan.
Pre: 0 <= index < size()
Post: element på plats index är borttaget
ur listan
Beskrivning: Kollar om ett element finns remove(in: index (heltal))
i listan.
Pre: sant
Beskrivning: Kollar om listan är tom.
Post: resultat = sant om elementet i
Pre: sant
listan, annars falskt
Post: resultat = sant om listan är tom,
contains(in: element, ut: boolskt värde) annars falskt
isEmpty(ut: boolskt värde)
Beskrivning: Lägger till ett element på
viss plats i listan.
Beskrivning: Bestämmer listans storlek.
Pre: 0 <= index <= size()
Pre: sant
Post: element är lagt till listan på plats
Post: resultat = listans storlek
index
size(ut: heltal)
6
add(in: element, index (heltal))
ADT:n Kö
• Exempel på egenskaper:
- En ordnad sekvens av element.
- Kan innehålla ett obegränsat antal element.
- FIFO (first in first out).
• Exempel på operationer:
Beskrivning: Skapar en tom kö.
Pre: sant
Post: en ny tom kö har skapats
Kö()
Beskrivning: Lägger till ett element i
kön.
Pre: sant
Post: element är lagt sist i kön
enqueue(in: element)
Beskrivning: Tar bort elementet först
i kön.
Pre: !isEmpty()
Post: elementet först i kön är borttaget
och returnerat
dequeue(ut: element)
Beskrivning: Kollar om kön är tom.
Pre: sant
Post: resultat = sant om kön är tom,
annars falskt
isEmpty(ut: boolskt värde)
7
ADT:n Stack
• Exempel på egenskaper:
- En ordnad sekvens av element.
- Kan innehålla ett obegränsat antal element.
- LIFO (last in first out).
• Exempel på operationer:
Beskrivning: Skapar en tom stack.
Pre: sant
Post: en ny tom stack har skapats
Stack()
Beskrivning: Lägger till ett element på
stacken.
Pre: sant
Post: element är lagt överst på stacken
push(in: element)
Beskrivning: Tar bort elementet överst
på stacken.
Pre: !isEmpty()
Post: elementet överst på stacken är
borttaget och returnerat
pop(ut: element)
Beskrivning: Kollar om stacken är tom.
Pre: sant
Post: resultat = sant om stacken är tom,
annars falskt
isEmpty(ut: boolskt värde)
8
Gränssnitt
• Exempel på Javagränssnitt för ADT:erna Kö och
Stack:
public interface QueueADT<E> {
public void enqueue(E element);
public E dequeue();
public boolean isEmpty();
}
public interface StackADT<E> {
public void push(E element);
public E pop();
public boolean isEmpty();
}
9
Implementationer av ADT:er
• En ADT kan implementeras på många sätt. Hur man
implementerar en ADT spelar inte någon större roll
så länge man får med de egenskaper och
operationer som angetts i ADT:n.
• Exempelvis kan ADT:n Stack implementeras med
hjälp av en lista, array eller noder.
10
Listimplementation av ADT:n Stack
• En Javalistklass (DefaultListModel) används för att
spara elementen i stacken.
• DefaultListModel kan användas tillsammans med
JList för att visa elementen i ett GUI.
• Toppen på stacken har valts till index=0.
• Tips: Denna implementation kan till vissa delar
användas till lab 4.
11
Arrayimplementation av ADT:n Stack
• Storleken på arrayen har valts till 20. Stacken har
alltså en övre gräns.
• Förvillkoret till operationen push blir då att stacken
inte är full. Detta måste kontrolleras i PushButtonklassen.
• Klassen ärver AbstractListModel och implementerar
gränssnittet ListModel för att den ska kunna
användas tillsammans med JList.
• Botten till stacken har valts till index 0 för att slippa
omflyttningar av element.
0
12
Nodimplementation av ADT:n Stack
• Elementen i stacken lagras som länkade noder.
• Insättning och borttagning görs i början av kedjan av
effektivitetsskäl. Den blir då toppen av stacken.
• Vi får skapa en Node-klass för noderna där man kan
spara ett stackelement och en “pil” till nästa nod
(länk).
• Klassen ärver AbstractListModel och implementerar
gränssnittet ListModel av samma skäl som i arrayimplementationen.
13
Stackapplikationer
• Reverse: Vända på strängar.
• Exempel: Vänd på “Kalle” med hjälp av en stack.
“Kalle”
“alle”
“lle”
e
l
l
a
K
l
a
K
a
K
K
“”
“le”
“e”
“el”
“ell”
l
l
a
K
l
a
K
a
K
“ella”
K
“e”
“”
l
l
a
K
e
l
l
a
K
“ellaK”
14
Stackapplikationer
• IsPalindrom: Kollar om en sträng är likadan oavsett
om man läser den fram- eller baklänges.
• Exempel: “anna”, “nitalarbralatin”, “olaSalo”
“olaSalo”
“alo”
=?
a
l
o
“laSalo”
“aSalo”
o
l
o
“lo”
“o”
=?
“Salo”
a
l
o
=?
l
o
o
15
Stackapplikationer
• IsBalanced: Kollar om ett programs parenteser är
balanserade. Parenteserna är (, ), [, ], {, }.
• Exempel: “([]{})”, “public class Test { public Test(){}}”
• Lösningsförslag:
- gå igenom strängen (programmet) från
vänster till höger,
- om tecknet är en vänsterparentes, lägg
parentesen på stacken,
- om tecknet är en högerparentes poppa
stacken och jämför parenteserna,
- andra tecken ignoreras,
- om alla parentesjämförelser “gått igenom”
och stacken är tom i slutet är programmet
balanserat
16