Föreläsning 3: Abstrakta datastrukturer, kö, stack, lista

Föreläsning 3: Abstrakta
datastrukturer, kö, stack, lista
•
•
•
Abstrakt stack
Abstrakt kö
Länkade listor
Abstrakta datatyper
Det är ofta praktiskt att beskriva vilka operationer man vill kunna göra på sina data
utan att behöva tänka på hur operationerna ska implementeras (dvs hur programkoden
ska se ut). En datastruktur som beskrivs på detta sätt kallas för en abstrakt datatyp.
En abstrakt datatyp
•
•
Anger inte lagringssättet
Specificerar operationer för åtkomst och ändring
Stack
En stack fungerar som en trave tallrikar - det man lägger överst på stacken är det som
kommer att tas bort först. För en abstrakt stack finns följande operationer:
push(x)
x=pop()
IsEmpty()
Lägg x överst på stacken.
Hämta det som ligger överst på stacken.
Undersök om stacken är tom.
Den som använder datatypen behöver inte (och får inte heller) bry sig om hur den
representeras. I Java definierar man lämpligen först ett gränssnitt (interface) för den
abstrakta datatypen. Implementationen blir sedan en klass som implementerar
gränssnittet och där alla instansvariabler är privata. Så här skulle ett gränssnitt för en
stack kunna se ut:
interface Stack {
void push(Object x);
Object pop();
boolean isEmpty();
}
Skriv programmet LadiesFirst.java som läser en fil av typen med personnummer och
namn och först skriver ut alla kvinnor och sedan alla män i filen.
120203-1114 Albus Dumbledore
330401-6402 Minerva McGonagall
920731-3131 Harry Potter
2D1320 Alexander Baltatzis
Männen måste tillfälligt läggas i ett förvaringsutrymme medan filen läses igenom.
Man skulle kunna använda en vektor String[] om man visste att det fanns högst
hundra män, men vi ska i stället använda en abstrakt stack. Man lägger en textrad på
stacken med anropet stack.push("En textrad") och man hämtar en textrad från
stacken med raden=stack.pop(). Med koden if (stack.isEmpty()) ... ska man
kunna kolla om stacken är tom.
import java.io.*;
class LadiesFirst {
public static void main(String[] args) {
String filnamn = args[0];
String personrad;
BufferedInputStream infil = Mio.openRead(filnamn);
Stack stack = new TildaStack();
while (!Mio.eof(infil)) {
personrad = Mio.getLine(infil);
int nästSistaSiffran = personrad.charAt(9) – ’0’;
if (nästSistaSiffran % 2 == 0)
System.out.println("Kvinna: " + personrad);
else
stack.push(personrad);
}
while (!stack.isEmpty()) {
personrad = (String) stack.pop();
System.out.println("Man: " + personrad);
}
}//main()
}//Ladiesfirst
Här har vi programmerat abstrakt, som om push och pop vore fungerande metoder.
Stackimplementationen kommer lite senare!
Kö
En kö fungerar som man förväntar sig, dvs det man stoppar in först är det som tas ut
först. För en abstrakt kö finns följande operationer:
enqueue(x)
X=dequeue()
IsEmpty()
Stoppa in x sist i kön.
Hämta det som står först i kön.
Undersök om kön är tom.
En kö kan t ex användas för att hantera skrivarköer. Den som skrev ut först ska också
få ut sin utskrift först. I labb 2 ska ni använda en kö för att förbereda en kortkonst!
Länkade listor
En länkad lista består av ett antal objekt, noder som är sammanlänkade genom att
varje nod refererar till nästa nod. Dessa referenser kallas ofta next-pekare. Klassen
Node skulle kunna användas för att skapa en länkad lista med heltal.
2D1320 Alexander Baltatzis
class Node{
int info;
Node next;
}//Node
Stack
Här kommer nu klassen TildaStack, en stack implementerad med en länkad lista.
Stacken kan också implementeras på andra sätt, t ex med en array (Javas Stack är
implementerad med en Vector).
class TildaStack implements Stack {
private Node top;
// Konstruktor
public TildaStack(){
top = null;
}//TildaStack()
public void push(int n){
Node nynod = new Node();
nynod.info = n;
nynod.next = top;
top = nynod;
}//push()
public int pop(){
int n = top.info;
top = top.next;
return n;
}//pop()
public boolean isEmpty(){
if (top == null)
return true;
else
return false;
}//isEmpty()
}//TildaStack
Datadelen info skulle kunna vara String men en generellare stack får man genom att
använda Object. Ersätt int med Object överallt. Det kan vara praktiskt med en
konstruktor i Node också och då blir det så här.
class Node{
Object info;
Node next;
// Konstruktor
public Node(Object info){
this.info = info;
this.next = null;
}
}
2D1320 Alexander Baltatzis
class TildaStack implements Stack {//stack som lagrar objekt
private Node top;
// Konstruktor
public TildaStack(){
top = null;
}
public void push(Object info){
Node nynod = new Node(info);
nynod.next = top;
top = nynod;
}
public Object pop(){
Object info = top.info;
top = top.next;
return info;
}
public boolean isEmpty(){
if (top == null)
return true;
else
return false;
}
}//TildaStack
Kö
En kö kan implementeras som länkad lista med samma noder men med en pekare
även på sista noden. Där ska nämligen nya noder stoppas in.
class Queue {//kö som lagrar objekt
private Node head, tail;
// Konstruktor
public Queue(){
head = null;
tail = null;
}
public void enqueue(Object info){
Node nynod = new Node(info);
if (isEmpty())
head = nynod;
else
tail.next = nynod;
tail = nynod;
}
public Object dequeue() {/* samma som pop för en stack*/}
public boolean isEmpty() {/* samma som för en stack */}
}
2D1320 Alexander Baltatzis
class LadiesFirst {
public static void main(String[] args) {
String filnamn = args[0];
String personrad;
BufferedInputStream infil = Mio.openRead(filnamn);
Stack stack = new TildaStack();
while (!Mio.EOF(infil)) {
personrad = Mio.getLine(infil);
int nästSistaSiffran = personrad.charAt(9) – ’0’;
if (nästSistaSiffran % 2 == 0)
System.out.println("Kvinna: " + personrad);
else
stack.push(personrad);
}
while (!stack.isEmpty()) {
personrad = (String) stack.pop();
System.out.println("Man: " + personrad);
}
}
}
interface Stack {
void push(Object x);
Object pop();
boolean isEmpty();
}
class TildaStack implements Stack {
private Node top;
// Konstruktor
public TildaStack(){
top = null;
}//TildaStack()
public void push(int n){
Node nynod = new Node();
nynod.info = n;
nynod.next = top;
top = nynod;
}//push()
public int pop(){
int n = top.info;
top = top.next;
return n;
}//pop()
public boolean isEmpty(){
if (top == null)
return true;
else
return false;
}//isEmpty()
}
2D1320 Alexander Baltatzis