Document

Datastrukturer och algoritmer
(Python)
Algoritmer och listor
1
Innehåll
• Algoritmer och pseudokod som ett sätt att
beskriva dem.
• Abstrakta datatypen lista och
algoritmmönster för lista.
• Olika sätt att konstruera lista och riktad
lista.
2
Algoritmer
• Vad är det?
• Mer formellt om algoritmer
– beräkningsbarhet
• Att beskriva algoritmer
• Analysera algoritmer
– Exekveringstid, minnesåtgång…
3
Vad är en algoritm?
• Recept som man följer
för att lösa ett givet
problem på ett
Recept
strukturerat sätt
• Ändlig stegvis
beskrivning av en ändlig
process
Ingredienser
Ugn,
plåtar, etc
Bullar
4
Algoritm?
Ingredienser
• Texten som beskriver algoritmen
är fix stor
– Receptet har samma storlek oavsett hur
många bullar som bakas.
• Processen kan variera i storlek
– Antalet bullar som bakas kan
variera.
Recept
Ugn,
plåtar, etc
• Kornighet i en algoritm
– Grovkornig:
1. Blanda mjöl och bakpulver i en skål.
– Finkornig:
1. Ta fram en skål som rymmer 5l
2. Ta fram ett decilitermått
3. Mät upp X dl mjöl
4. Häll mjölet i skålen
….
Bullar
5
Exempel
•
Antag att vi har en lista på alla anställda på ett
företag: Namn, Pnr, lön, etc. Vi vill räkna ut
lönekostanden för företaget.
1.
2.
3.
Skriv ner talet 0
Gå igenom listan, och för varje anställd så
adderar man du personens lön till det skrivna
talet
När man nått slutet på listan så är det
nedskrivna talet resultatet
6
Algoritmer mer formellt
Definition:
Algoritm är en noggrann plan,
en metod för att stegvis utföra något
7
Krav på algoritmer
• Ändlighet
– Algoritmen måste sluta
• Bestämdhet
– Varje steg måste vara entydigt
• Indata
– Måste ha noll eller flera indata
• Utdata
23. Donald Knuth
– Måste ha ett eller flera utdata
• Effektivitet/Genomförbarhet
– Varje steg i algoritmen måste gå
att utföra på ändlig tid
8
Algoritmer mer formellt
• Reglerna för algoritmer beskriver inte
tillräckligt tydligt vad det är man kan göra i
form av algoritmer – vad som är
beräkningsbart.
• Definition av beräkningsbarhet: Ett
problem är beräkningsbart omm det finns
en Turingmaskin som löser problemet.
Turing maskin
9
Att (be)skriva algoritmer
• Vi behöver ett språk som:
– Är strukturerat och formellt
– Mindre formellt än programmeringsspråk
• Ingen typning
• Dynamisk bindning
• Räckvidd
10
Pseudokod
• Mix av naturligt språk och
programmeringsspråk
• Influenser från matematisk notation
 används för tilldelning
= används för likhetsrelationen
• Funktionsdeklaration
– Algorithm name(param1,param2)
11
Pseudokod –
programkonstruktioner
• Valstrukturer:
– if…then…[else…]
• Villkorsloopar:
– while…do
– repeat … until…
• Räkneloopar:
– for…do
• Anrop:
– algoritmName(args)
• Arrayindexering:
– A[i]
• Returnera värden:
– return value
12
Pseudokod – exempel
Algorithm arrayMean(v,n)
input: An array v storing n integers
output: The average of the n elements
in v
sum  v[0]
for i  1 to n-1 do
sum  sum + v[i]
return sum/n
13
Pseudokod
• Vi använder oss av pseudokod för att
beskriva algoritmer
• Det finns inget universellt språk utan
många dialekter
• Alla döljer mycket av programspråkens
designval, dvs. pseodokoden är
programspråksoberoende
14
Implementation av pseduokoden i
två olika språk
C
float arrayMean(float *v, int n){
float sum = v[0];
for (int i = 1; i < n; i++)
sum = sum + v[i];
return sum/n;
}
Python
def arrayMean(v,n):
sum = v[0]
for i in range(1,n):
sum = sum + v[i]
return sum/n
15
Lista
• Generisk datatyp (polytyp)
– Lista av typ
• Typ kan vara av vilken typ som helst
• Instansiering: ger typparametern ett värde tex Lista av
Heltal som fortfarande är en ADT
• Homogen datatyp
– Alla element har samma typ
• Ex på listtyper
– lista av heltal (3 12 –7 23 5)
– lista av tecken (‘a’, ‘r’, ‘t’)
– lista av (lista av heltal) ((5 27 18) (43 5) (2 0 9))
16
Lista
• Modell
– Pärm
• Bläddra, inspektera, lägga till, ta bort
• Konstruktion
– Dynamiskt med hjälp av länkade celler
• Dynamisk datatyp: Kan modifiera objektets struktur
(storlek)
– Statiskt med hjälp av fält/arrayer
17
Lista
•
•
•
•
Ändligt antal linjärt ordnade element
Första / sista element
Före / efter relation
Dynamisk datatyp
– Struktur och storlek förändras under
datatypens livslängd
18
Lista
• Element
– Värde och position
• Struktur
– Bortser från elementvärden
• Position
– Plats i strukturen
– positionsbeskrivningar förändras när element sätts in eller
tas bort
– positionen är elementets förhållande till objektet i övrigt
– hur man anger positioner avgörs vid konstruktionen av
datatypen.
– strukturförändrande operationer behöver returnera nytt
positionsvärde
19
Riktad Lista
• Modell
– Slalombana
• Kan bara flytta sig framåt
• Specialisering av Lista
20
Gränsyta till Riktad Lista
abstract datatype DList(val)
auxiliary pos
Empty() -> DList(val)
Insert(v:val,p:pos,l:DList(val))
->(DList(val),pos)
Isempty (l:DList(val)) -> Bool
Inspect (p:pos,l:DList(val)) -> val
First (l:DList(val)) -> pos
Isend (p:pos,l:DList(val)) -> Bool
Next(p:pos,l:DList(val)) -> pos
Remove((p:pos,l:DList(val))
->(DList(val),pos)
21
Dynamiska resurser
• Skapar dataobjekt för tillfälliga behov
– Kill- lösgör resurser
– Create - reserverar resurser
– Vålnader
• minne som är avallokerat, men som vi fortfarande refererar till
• Sophämtning
– Administrativ procedur identifierar och återvinner objekt
som inte utnyttjas
• I Python behöver programmeraren inte hantera
skapande och återlämnandet. Det sköts internt av
Python
– Har en egen “minnespool” så att kommunikationen med
operativsystemet minimeras.
22
Länk
•
•
•
•
•
Referens, pekare
Fysisk datatyp i många programspråk
Objekt som refererar till annat objekt
Konstrueras oftast som index i fält (kursor)
Billigare kopiera länkar till objekt än
objekten själva
23
Gränsyta till Länk
Abstract datatype
Make
Nil
Isnil
Follow
Equal
Link (obj)
(x : obj) -> Link (obj)
( ) -> Link (obj)
(l : Link (obj)) -> Bool
(l : Link (obj)) -> obj
(l1,l2 : Link (obj)) -> Bool
24
Gränsyta till Lista
abstract datatype List(val)
auxiliary pos
Empty() -> List(val)
Insert(v:val,p:pos,l:List(val))->(List(val),pos)
Isempty (l:List(val)) -> Bool
Inspect (p:pos,l:List(val)) -> val
First (l:List(val)) -> pos
End (l:List(val)) -> pos
Next(p:pos,l:List(val)) -> pos
Previous(p:pos,l:List(val)) -> pos
Remove((p:pos,l:List(val))
->(List(val),pos)
25
Skillnad mellan Lista och Riktad
lista
• I Lista finns previous- och endoperationer så att vi kan navigera åt båda
hållen
• Riktad lista har en isend operation istället
för end.
26
Algoritmmönster för lista
• Traversering
– Besöker systematiskt alla element
• Sökning
– Söker det första elementet som uppfyller ett
bestämt villkor
• Filtrering
– Filtrerar ut alla element som uppfyller ett
bestämt villkor
27
Algoritmmönster för lista
• Reduktion
– Beräknar en funktion av objektets
elementvärden
• Ex. Summera alla tal i en lista
• Mappning
– Transformera varje elementvärde i en
datastruktur
• Ex. multiplicera alla talen i en lista med 4
28
Traversering
Algorithm traverse(list, myfunc)
input: A list and a function to apply to
all elements in a list
output: Besöker systematiskt alla element
pos  first(List)
while not isEnd(List, pos):
func(inspect(List, pos))
pos  next(List, pos)
def traverse(list, func):
pos = list.first()
while not list.isEnd(pos):
func(list.inspect(pos))
pos = list.next(pos)
29
Algorithm seek(list, func)
Sökning
input: A list and a function to compare an element
with the one we seek
output: Söker efter ett element
found  False
pos  first(List)
while not found and not isEnd(List, pos)
if func(inspect(List, pos)) then
found  True
foundPos  pos
else
pos  next(listpos)
if found then
return (True, foundPos)
else
return (False, None)
30
Filtrering
Algorithm filter(list, func)
newList  empty()
pos  first(List)
while not isEnd(List, pos)
val  inspect(list, pos)
if func(val) then
insert(newList, first(newList), val)
pos  next(List, pos)
return newList
31
Reduktion
Algorithm reduce(list, func)
pos = first(list)
val1 = inspect(list, pos)
pos = next(list, pos)
val2 = inspect(list, pos)
pos = next(list, pos)
res = func(val1, val2)
while not list.isEnd(pos):
res = func(res, inspect(list, pos))
pos = next(list, pos)
return res
32
Mapping
Algorithm map(list, func)
newList  empty()
pos  first(List)
while not isEnd(List, pos)
val  func(inspect(list, pos))
insert(newList, first(newList), val)
pos  next(List, pos)
return newList
33
Sätt att konstruera lista
• Lista
– Lista som fält
– Lista konstruerad med 2-Cell
34
34
Lista som Fält
• Fördelar
– Snabb inspektion av element
• Fast bara om man utnyttjar att man vet hur position är
implementerad vilket man inte borde göra
• Nackdelar
– Fast reserverat utrymme
• Går delvis att komma runt genom att skapa en ny större
array vid behov (detta är dock kostsamt)
• Kostsamt sätta in / ta bort element
– Måste flytta delar av listan framåt eller bakåt för att
rymma det nya elementet.
35
Länkade strukturer
• Fördelar
– Insättning / borttagning går snabbt
– Minnesutrymmet är proportionellt mot storleken
– Allokerar minne när det behövs
• Nackdelar:
– Länkarna behöver också minnesutrymme
– Kommer bara åt listelement genom att
traversera från listans början eller slut
36
Dubbellänkad Lista
• Länkar mellan elementen
• Elementen är en cell som består av länkar
och värde
37
Riktad Lista
• Konstruerad som
– Fält
– Dubbellänkad Lista
– Enkellänkad Lista
• Enkellänkad Lista
– Mer ekonomisk
38
Enkellänkad Lista
• Problem vid insättning
• Lösning:
– Representera position mha en länk till
föregångarelementet
– Listhuvud
• Tomma objekt
• Gränspositioner
39
Enkellänkad Lista
• Konstruktion utan huvud
– Stopplänkvärde (nil, null)
– Insättning före elementet X
•
•
•
•
Skapa en ny cell
Sätt in den efter X
Kopiera X:s värde till den nya cellen
Sätt X:s värde till v
40
n-länkad Cell
• Tippel som består av
– ett värde
– n stycken länkar
• Byggmaterial för andra datatyper
• n-länkad struktur
– Objekt konstruerade med n-länkade celler
• Listor, träd
41
Gränsyta till 1Cell
abstract datatype 1Cell(val)
Create () -> 1Cell(val)
Set-value(v:val,c:1Cell(val)) -> 1Cell(val)
Set-Link (l:Link(1Cell(val)),c:1Cell(val)) -> 1Cell(val)
Inspect-value (c:1Cell(val))-> val
Inspect-link (c:1Cell(val))-> Link(1Cell(val))
Kill (c:1Cell(val))
42
1Cell i Python
class OneCell:
def __init__(self):
self._data = None
self._link = None
def setValue(self,data):
self._data = data
def setLink(self,link):
self._link =link
def inspectValue(self):
return self._data
def inspectLink(self):
return self._link
43