2 Modul 2 - (Länkade) Listor

Relevanta dokument
Tommy Färnqvist, IDA, Linköpings universitet

6 Rekursion. 6.1 Rekursionens fyra principer. 6.2 Några vanliga användningsområden för rekursion. Problem löses genom:

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 3 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Föreläsning 4. Kö Implementerad med array Implementerad med länkad lista Djup kontra bredd Bredden först mha kö

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 3 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Föreläsning 2. Länkad lista och iterator

Datastrukturer. föreläsning 3. Stacks 1

TDIU01 - Programmering i C++, grundkurs

Föreläsning 2. Länkad lista och iterator

F12 - Collections. ID1004 Objektorienterad programmering Fredrik Kilander

Föreläsning 2 Datastrukturer (DAT037)

Föreläsning 6: Introduktion av listor

Föreläsning Datastrukturer (DAT036)

Datastrukturer och algoritmer

Länkade strukturer. (del 2)

Föreläsning 12. Länkade listor

Datastrukturer, algoritmer och programkonstruktion (DVA104, VT 2015) Föreläsning 6

Föreläsning 10. ADT:er och datastrukturer

Listor. Koffman & Wolfgang kapitel 2, avsnitt , och 2.9

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

Programmering för språkteknologer II, HT2014. Rum

Föreläsning 11. ADT:er och datastrukturer

Abstrakt datatyp. -Algoritmer och Datastrukturer- För utveckling av verksamhet, produkter och livskvalitet.

TDDC76 - Programmering och Datastrukturer

Datastrukturer. Arrayer. Arrayer. Arrayer. Array av arrayer. Array av arrayer

maxlist-1. Indexerad lista Länkad lista

Länkade strukturer, parametriserade typer och undantag

Abstrakta datatyper. Primitiva vektorer. Deklarera en vektor

Föreläsning 4. ADT Kö Kö JCF Kö implementerad med en cirkulär array Kö implementerad med en länkad lista

TDP004. Minne och pekare. Eric Elfving Institutionen för datavetenskap

Programmering i C++ EDA623 Dynamiska datastrukturer. EDA623 (Föreläsning 11) HT / 31

Länkade listor kan ingå som en del av språket, dock ej i C Länkade listor är ett alternativ till:

1 Klasser och objektorientering Vad är objektorientering?

TDDC76 - Programmering och Datastrukturer

Abstrakta datastrukturer

Programmering i C++ EDAF30 Dynamiska datastrukturer. EDAF30 (Föreläsning 11) HT / 34

Dugga Datastrukturer (DAT036)

ADS : STACK ADT: STACK. Stack och Kö -Implementering - Tilllämpningar. Oftast förekommande metoder i Stack. TopOfStack

Exempeltenta GruDat 2002/2003

Avbildningar och hashtabeller. Koffman & Wolfgang kapitel 7, mestadels avsnitt 2 4

TDDC30 Programmering i Java, Datastrukturer och Algoritmer Lektion 2. Länkade listor Stackar Köer MyList Iteratorer Lab 2 Exceptions Paket

ADT Kö. Seminarium 4 Köer och Stackar Innehåll. Operationer. ADT Stack. Definition. Definition

Föreläsning Datastrukturer (DAT036)

Tentamen. Programmeringsmetodik, KV: Java och OOP. 17 januari 2002

Föreläsning 4 Innehåll. Abstrakta datatypen lista. Implementering av listor. Abstrakt datatypen lista. Abstrakt datatyp

Den som bara har en hammare tror att alla problem är spikar

Föreläsning 4. ADT Kö Kö JCF Kö implementerad med en cirkulär array Kö implementerad med en länkad lista Läsanvisningar och uppgifter

Föreläsning Datastrukturer (DAT037)

Teoretisk del. Facit Tentamen TDDC kl (6) 1. (6p) "Snabba frågor" Alla svar motiveras väl.

Tentamen Datastrukturer (DAT037)

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 9 Jonas Lindgren, Institutionen för Datavetenskap, LiU

EDAA20 Föreläsning Klassen ArrayList. Viktiga operationer på ArrayList. Generisk klass

Det finns många flaggor till g++,

Tentamen Datastrukturer D DAT 035/INN960 (med mycket kortfattade lösningsförslag)

Tentamen Datastrukturer (DAT036)

Föreläsning 3 Datastrukturer (DAT037)

Föreläsning 1. Abstrakta datatyper, listor och effektivitet

TDIU01 Programmering i C++

TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 5 Erik Nilsson, Institutionen för Datavetenskap, LiU

TDDC30 Programmering i Java, Datastrukturer och Algoritmer Lektion 2. Laboration 2 Datastrukturer En liten uppgift Frågor

Föreläsning 4 Datastrukturer (DAT037)

Föreläsning 9 Datastrukturer (DAT037)

Föreläsning 4 Innehåll

Kurskod D0010E Datum Skrivtid 5tim

Tentamen i Algoritmer & Datastrukturer i Java

Samlingar Collection classes

Föreläsning 3 Datastrukturer (DAT037)

Föreläsning 14 Innehåll

Lösningsförslag för tentamen i Datastrukturer (DAT037) från

Föreläsning REPETITION & EXTENTA

Tentamen Datastrukturer (DAT036)

Föreläsning 2 Datastrukturer (DAT037)

Föreläsning Datastrukturer (DAT036)

Tentamen Programmeringsteknik II Inledning. Anmälningskod:

Programmering i C++ EDA623 Mallar. EDA623 (Föreläsning 12) HT / 29

Datastrukturer och algoritmer

Tentamen Datastrukturer (DAT036)

Det är principer och idéer som är viktiga. Skriv så att du övertygar rättaren om att du har förstått dessa även om detaljer kan vara felaktiga.

Objektorienterad programmering i Java

Fortsä'ning Pekare. Ulf Assarsson. Originalslides av Viktor Kämpe

Föreläsning 2. Stackar, köer och listor TDDC91,TDDE22,725G97: DALG. Innehåll. 1 ADT stack. 1.1 Tillämpningar

Minnestilldelning (allokering) och frigörande (avallokering) av minne

Klasser. Det är egentligen nu som kursen i programmeringsteknik börjar..., s k objektorienterad programmering.

Datastrukturer och algoritmer

Övning från förra gången: readword

Klassen BST som definierar binära sökträd med tal som nycklar och enda data. Varje nyckel är unik dvs förekommer endast en

Datastrukturer och algoritmer. Föreläsning 4 Test, Stack och Kö

Föreläsning 3. Stack

Föreläsning 8 Datastrukturer (DAT037)

OOP Objekt-orienterad programmering

Föreläsning Datastrukturer (DAT036)

public static void mystery(int n) { if (n > 0){ mystery(n-1); System.out.print(n * 4); mystery(n-1); } }

Namn: (Ifylles av student) Personnummer: (Ifylles av student) Tentamensdatum: Tid: Hjälpmedel: Inga hjälpmedel

Föreläsning 3. Stack

Tommy Färnqvist, IDA, Linköpings universitet. 1 ADT Map/Dictionary Definitioner Implementation... 2

KLASSER. Inkapsling Abstrakt datatyp Public och private. Klassmedlemmar Datamedlemmar Exempel Funktionsmedlemmar

1 Namnkontroll (NameControl)

BINÄRA TRÄD. (X = pekarvärdet NULL): struct int_bt_node *pivot, *ny; X X X 12 X X 12 X X -3 X X

Tentamen Datastrukturer D DAT 035/INN960

Programmering B med Visual C

Transkript:

2 Modul 2 - (Länkade) Listor 2.1 Jämförelse mellan "verkliga" och "virtuella" listor Verklig Ta ett blankt papper Skriv en punkt Lägg till fler punkter Läser vad som står vid en punkt Stryker över/suddar en punkt Kollar hur mycket som skrivits in på pappret. Kolla om listan är tom. Leta efter en viss punkt Slänger papperet när listan inte behövs längre. Virtuell Skapa ny lista (exempelvis som ett objekt av en klass) Lägg till ett element Som ovan Hämtar elementet på en viss position i listan Ta bort ett element från listan på en viss position. Fråga listan hur många element som finns inlagda. Fråga listan om den är tom. Sök i listan efter ett visst element. Raderar hela listan. 2.1.1 Hur skulle dessa funktioner kunna översättas till operationer för en lista som ska implementeras som en klass i C++? Här är en första grov skiss. class List public: List(); ~List(); //Lägg till ett element void insert(element e); //konstruktor, Skapa ny lista //destruktor, Raderar hela listan. // Hämtar elementet på en viss position i listan Element getelement(int position); // Ta bort ett element från listan på en viss position void remove(int position); // Fråga listan hur många element som finns inlagda int size(); ; // Fråga listan om den är tom bool isempty(); //o s v private: //...

2.2 Länkade listor Länkade listor: är dynamiska (blir större el. mindre vid behov) är uppbyggda av noder som innehåller data plus en pekare. kräver sekventiell genomgång tar aldrig mer plats än nödvändigt kräver extra utrymme i noden för en pekare som kan peka på nästa nod. data data data. pekare pekare pekare

2.3 insert Ofta vill man kunna sätta in ett element på vilken position som helst i en lista. insert(position, item) (OBS! Pseudokod) Allmänt Lägger till elementet "item" på position "position" i listan. Förutsättning "position" måste vara en giltig position i listan. Vilka positioner är giltiga? Det måste finnas ledigt utrymme i listan om den är begränsad. Är det vanligt att en länkad lista är begränsad? Anmärkning: Dessa förutsättningar utgör egentligen förvillkor till operationen listinsert. Ni har stött på förvillkor i kursen Programmeringstenik. Vi ska nu börja tillämpa kontrakt, där förvillkor och eftervillkor ingår, mer systematiskt. Effekt Resultatet är att det nya elementet "item" lagts in på positionen "position". Det element som eventuellt befann sig där tidigare samt efterföljande element har förskjutits en position upp. Anmärkning: Den effekt som beskrivs kan endast garanteras såvida förutsättningarna är uppfyllda enligt ovan. Detta utgör eftervillkoret. Exempel 1 Exempel på listinsert. Före: mjölk, ägg, smör, äpplen, bröd, kyckling Operation: listinsert(4, nötter) Efter: mjölk, ägg, smör, nötter, äpplen, bröd, kyckling

2.4 Olika implementationer av listor Om vi talar om en lista generellt har detta inget att göra med hur den kan representeras. En ADT lista säger heller inget om hur listan ska representeras. ADTn säger att det finns en abstrakt datatyp som heter lista och denna har alltid vissa operationer knutna till sig. Operationer som kan utföras på listan. Om vi ska representera en lista som mjukvara säger vi att vi ska implementera en lista. Det finns olika sätt att implementera en lista som en mjukvarumodul. Nedan beskrivs några specifika implementationer för att representera en lista som mjukvara. Array - Fördelar - Lätt att implementera - Effektiv för sortering, sökning, hämta element. Varför? - Nackdelar - Ineffektiv för att lägga till och ta bort element. Varför? - Bestämd storlek (innebär overhead och problem vid full lista) - En del minne går outnyttjat. Länkad lista - Fördelar - Dynamisk, d v s växer vid behov, inga problem med att listan blir full. Enda begränsningen är det minne som finns tillgängligt i datorn. - Inget outnyttjat minne. - Effektiv för att lägga till och ta bort element. Varför? - Nackdelar - Liten overhead för pekare till varje nod, detta är dock i de flesta fall försumbart. - Lite svårare att implementera, minneshanteringen måste skötas manuellt. - Ineffektiv för sortering, sökning, hämta element. Varför? Fil - direktindexering (på något lagringsmedium) - Fördelar - Dynamisk. Ingen overhead annat än klusterstorlek (minsta skrivbara enhet på disken.) - Bestående, d v s den finns kvar på mediet då programmet avslutats. - Nackdelar - Alla operationer är hemskt ineffektiva. Varför? 2.4.1 Användande av listor i mjukvara Vilken implementation av listan ska man välja? Det beror av de behov man har. Exempel på frågeställningar är: Är det OK om listan är begränsad eller inte? Vilka operationer ska utföras mest? Man vill ju ha ett så effektivt användande som möjligt. Måste listan kunna sparas på ett beständigt medium? Nästan aldrig väljer man en filbaserad lista som är direktindexerad eftersom man måste accessa filen för varje operation. I stället är det troligt att man tillhandahåller funktionalitet i gränssnittet för listan för att kunna skiva/läsa hela listan på en gång till/från filen.

2.4.2 Gränssnittet för en lista Gränssnittet för en lista är det som klienten ser då denne ska använda listan. Då vi använder C++ för att implementera listan motsvaras gränssnittet av de operationer som finns i klassen under public-delen. Oavsett hur listan är implementerad ska gränssnittet se likadant ut. Om jag som klient använder listan är jag ointresserad av hur den är implementerad. Representationen av listan ska inte lysa igenom då man tittar på de operationer man kan använda!

Exempel 2 Allokering och borttagning av en nod i en länkad lista class Node friend class List; ; private: int data; Node* next; class List public: //... void addelement(int element); void removeelement(int position); //... private: Node* getnode(int position); Node* head; //Pointer to the first node in the list. int size; ; void List::addElement(int element) Node* newnode = new Node(); //create a new node newnode -> data = element; //add element to the node //Insert the node wherever you want in the list. //I recommend you to always insert the node first in the //list. //newnode -> next should be set to point to the next //node in the list. size += 1; void List::removeElement(int position) //Find the position of the node you want to remove. Node *nodetoremove = getnode(position); //Connect the nodes before and after the node to remove. delete nodetoremove; nodetoremove = 0; Angående klassen Node Ett objekt av klassen Node utgör en nod i den länkade listan. Om listan innehåller t ex 5 element kommer listan att bestå av 5 noder som är länkade. Därför innehåller varje nod en next-pekare (Node* next;) som kan peka på nästa nod. Förutom pekaren finns också en

variabel (int data;) som ska hålla elementet. I exemplet ovan betyder det att listan lagrar heltal. Klassen Node ser lite speciell ut i och med att den inte har några operationer, men det beror på att den endast existerar för att utgöra just en nod i en länkad lista, den ska inte användas till något annat. Därför kan den länkade listan istället få tillgång till de privata medlemmar som finns i noden. Denna tillåtelse får listan tack vare deklarationen friend class List; i klassen Node. Du behöver inte förstå varför just nu. Du behöver heller inte förstå hur friend fungerar. Acceptera bara tills vidare att klassen List kommer åt de privata medlemmarna i klassen Node. Det är endast för klassen Node som vi kommer att använda denna konstruktion m h a friend. Du kommer inte att vid något tillfälle behöva nyttja friend då du skriver dina klasser.

2.5 Funktioner för länkade listor 2.5.1 insert / add / sätt in / lägg till före efter ny nod ny nod 2.5.2 delete / remove / ta bort / före efter nod som ska bort 2.5.3 leta / find / search / look-up / hitta tillfällig pekare sökt element

2.6 Listhuvud För att kunna nå en länkad lista måste man veta var den börjar. Man sätter ett "handtag" på första elementet och detta handtag brukar kallas listhuvud eller head. Detta är en pekare till första elementet i listan. Listhuvudet pekar alltid på första elementet i listan. data data data head next next next

2.7 Insättning av en nod Algoritm: 1. Hitta rätt plats för insättning 2. Skapa en ny nod och lägg ny data i den 3. Koppla in den nya noden i listan genom att flytta pekare. En tillfällig pekare som pekar på den nod som föregår platsen där den nya noden ska sättas in behövs. Här kallas den prev, som är en förkortning av previous. head 5 10 100 next next next 7 prev next newptr newptr->next = prev->next; prev->next = newptr;

2.8 Insättning av en nod (forts.) Insättning först i listan är ett specialfall. head 5 100 next next 3 next newptr->next = head; head = newptr; newptr

2.9 Borttagning av en nod För borttagning krävs två tillfälliga pekare cur (current) och prev (previous). Algoritm: 1. Hitta noden som ska tas bort 2. Koppla ifrån noden genom att flytta pekare 3. Frigör minnet som användes av noden. bort head 5 8 10 next next next prev cur prev->next = cur->next; delete cur; cur = 0;

2.10 Borttagning av nod (forts.) Borttagning av första noden är ett specialfall. head 5 10 next next next cur head=head->next; delete cur; cur = 0; Eftersom denna operation påverkar head-pekaren får man se till att inte tappa bort den.

2.11 Visning av en listas innehåll Visningen av en listas innehåll är en funktion som varje klient får implementera själv. Det är inte generellt att inkludera en sådan funktion som en del av listans gränssnitt eftersom man måste utnyttja en bestämd utdataström, t ex cout. Exempel //=========================================== // displaylist: visar innehållet i en länkad lista // pre: true // post: Alla element i listan "list" är visade. //------------------------------------------------------------------ void displaylist(list& list) for(int i = 1; i <= list.size(); i += 1) cout << list.getelement(i) << endl;

2.12 Varianter på länkad lista Förutom den "vanliga" länkade listan som är enkellänkad finns två vanliga varianter: Dubbellänkad lista Cirkulär lista (enkel- eller dubbellänkad) Läs kursivt om dessa i boken. Vad har en dubbellänkad lista för fördel gentemot en enkellänkad lista?

2.13 Exempel på en enkel arraybaserad lista implementerad m h a en klass /****************List.h*******************/ class List public: //Pre: true //Post: An empty list has been created List(); //Pre:!isFull() //Post: 'element' has been added to the end of the list void add(int element); //Pre: 1 <= position <= size() //Post: result = the element at position "position" int getelement(int position); //Pre: true //Post: result = true if the list is full,false otherwise bool isfull(); //Pre: true //Post: result = the size of the list int size(); ; private: enumsize = 100; // used to initialize the size of the // array int list_elements[size]; int _size; /****************List.cpp*******************/ #include "List.h" List::List() _size = 0; void List:: add(int element) list_elements[_size] = element; _size += 1; int List::getElement(int position) return list_elements[position - 1]; bool List::isFull()

return (_size == SIZE); int List::size() return _size; /****************driver.cpp*******************/ #include "List.h" //Drivrutin för att lägga till ett element //Pre: true //Post: If the list "alist" was not full, an element selected by the //user has been added to it. void addelement(list& alist) int element = getuserinput(); if(!alist.isfull()) //Kontrollera förvillkoret alist.add(element); //Drivrutin för att skriva ut listan //Pre: true //Post: The elements of the list "alist" has been displayed. void printlist(list& alist) //print the list for(int i = 0 ; i < mylist.size(); i++) cout << mylist.getelement(i) << endl; int main() List mylist; int userchoice; do printmenu(); userchoice = matain(); switch(userchoice) case 1: addelement(mylist); break; case 2: printlist(mylist); break; //... while(...); return 0;