Tommy Färnqvist, IDA, Linköpings universitet



Relevanta dokument
TDIU01 - Programmering i C++, grundkurs

TDDC76 - Programmering och Datastrukturer

TDDC76 - Programmering och Datastrukturer

Föreläsning 6: Introduktion av listor

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

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

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

Föreläsning 4 Innehåll

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

Repetition av OOP- och Javabegrepp

OOP Objekt-orienterad programmering

Repetition av OOP- och Javabegrepp

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

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

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

TDIU01 Programmering i C++

F12 - Collections. ID1004 Objektorienterad programmering Fredrik Kilander

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

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

TDIU20 - Objektorienterad programmering i c++ - föreläsning 4

Datastrukturer. föreläsning 3. Stacks 1

Sammansatta datatyper Generics: Parametrisk polymorfism

2 Modul 2 - (Länkade) Listor

Länkade strukturer, parametriserade typer och undantag

Samlingar Collection classes

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

Föreläsning 3. Stack

maxlist-1. Indexerad lista Länkad lista

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

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

Länkade strukturer. (del 2)

public boolean containskey(string key) { return search(key, head)!= null; }

TDDC77 Objektorienterad Programmering

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

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

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

Abstrakta datatyper. Primitiva vektorer. Deklarera en vektor

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

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

Pekare. Pekare. Varför använder vi pekare? Vad är en pekare? Pekare. Deklaration/initiering av pekare

Lite om felhantering och Exceptions Mer om variabler och parametrar Fält (eng array) och klassen ArrayList.

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

Tentamen i Algoritmer & Datastrukturer i Java

Ett problem. Kontrollstrukturer och arrayer. Arrayer. Lösningen. Arrayer och hakparanteser. Exempel int[] results; results = new int[10]; // 0..

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

TDDC76 Programmering och datastrukturer

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

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

Exempel. Arrayer. Lösningen. Ett problem. Arrayer och hakparanteser. Arrayer

Föreläsning 3. Stack

Dynamiskt minne. Vad är dynamiskt minne Motivering Hur gör man i C Övningar

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

Föreläsning Datastrukturer (DAT036)

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

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

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

Innehåll. Pekaren this Självreferens. Klasser Resurshantering, representation. Överlagring av operatorer. Överlagring av operatorer

Föreläsning Datastrukturer (DAT036)

Datastrukturer och algoritmer

Tentamen Programmeringsteknik II och NV2 (alla varianter) Skriv bara på framsidan av varje papper.

Datastrukturer och algoritmer

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

Föreläsning 2 Datastrukturer (DAT037)

Föreläsning 1 Datastrukturer (DAT037)

Tentamen Programmeringsteknik II Inledning. Anmälningskod:

Innehåll. Pekare Exempel

Föreläsning 8: Exempel och problemlösning

Datastrukturer och algoritmer

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

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

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

Innehåll. Pekare Exempel

Föreläsning 10. Pekare (Pointers)

TDIU01 - Programmering i C++, grundkurs

Att deklarera och att använda variabler. Föreläsning 10. Synlighetsregler (2) Synlighetsregler (1)

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

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

Arrayer (fält)

Abstrakta datastrukturer

Introduktion till algoritmer - Lektion 3 Matematikgymnasiet, Läsåret Lektion 3

Tillämpad programmering

Föreläsning 8 SLUMPTAL, SIMULERING + INTRODUKTION TILL VEKTORER

Laboration A Objektsamlingar

Objektorienterad Programkonstruktion. Föreläsning 9 30 nov 2016

Tentamen'('Datastrukturer,'algoritmer'och'programkonstruktion.'

2D1387, Programsystemkonstruktion med C++ Johnny Bigert, Kursens hemsida:

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

DAT043 - föreläsning 8

Datatyper och kontrollstrukturer. Skansholm: Kapitel 2) De åtta primitiva typerna. Typ Innehåll Defaultvärde Storlek

Del A (obligatorisk för alla)

Sätt att skriva ut binärträd

Tentamen i Algoritmer & Datastrukturer i Java

Kurskod D0010E Datum Skrivtid 5tim

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

Föreläsning REPETITION & EXTENTA

Tentamen i DD2387 Programsystemkonstruktion med C++

Samlingar Collection classes

Föreläsning 12. Länkade listor

Det finns en referensbok (Java) hos tentavakten som du får gå fram och läsa men inte ta tillbaka till bänken.

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

Transkript:

Föreläsning 9 Pekare, länkade noder, länkade listor TDDD86: DALP Utskriftsversion av föreläsning i Datastrukturer, algoritmer och programmeringsparadigm 25 september 2015 Tommy Färnqvist, IDA, Linköpings universitet 9.1 Innehåll Innehåll 1 Pekare och länkade noder 1 1.1 Introduktion.......................................... 1 1.2 Pekare............................................. 1 1.3 Objekt............................................. 4 1.4 Länkade noder........................................ 5 2 Länkade listor 7 9.2 1 Pekare och länkade noder 1.1 Introduktion Arraybaserade datastrukturer Flera containrar använder en array/ett fält av element för lagring Vilka för/nackdelar finns det med att använda en array? Fördelar: snabbt att lägga till/ta bort i slutet; snabb åtkomst till elementen Nackdelar: långsamt att lägga till/ta bort i mitten av arrayen; ofylld array slösar med minne; behöver öka kapaciteten när den blir full 9.3 1.2 Pekare Länkade datastrukturer Andra containrar använder sammanlänkade nodobjekt för att lagra data Varje nodobjekt lagrar ett dataelement och en länk till någon annan nod Fördelar: snabbt att lägga till/ta bort data i alla positioner Nackdelar: långsamt att komma åt vissa delar av datastrukturen För att förstå länkade strukturer måste vi förstå pekare... 9.4 1

Minnesadresser När en variabel deklarerats lagras den någonstans i minnet Vi kan be om en variabels minnesadress med &-operatorn Minnesadresser skrivs vanligen som hexadecimala (bas-16) tal Många vanliga datatyper använder 4 bytes (32 bitar) minne int x = 42; int y = 17; int a[3] = {91, -3, 85; cout << x << endl; // 42 cout << &x << endl; // 0x7f8e20 cout << y << endl; // 17 cout << &y << endl; // 0x7f8e24 cout << &a[0] << endl; // 0x7f8e28 cout << &a[1] << endl; // 0x7f8e2c cout << &a[2] << endl; // 0x7f8e30 9.5 Pekare pekare: En variabel som lagrar en minnesadress Pekare deklareras med * efter typen de pekar till Vi kan referera till värdet pekaren pekar på genom att skriva * före pekaren int x = 42; int* p = &x; cout << p << endl; // 0x7f8e20 cout << *p << endl; // 42 *p = 99; cout << x << endl; // 99 9.6 Pekararitmetik Vi kan ändra vad en pekare pekar på med +, -, ++, --, etc. Att inkrementera en T* med 1 flyttar fram pekaren motsvarande storleken av en T i minnet Vi kan använda syntaxen [k] för att komma åt minne k platser bort från pekaren (En arrayvariabel är egentligen bara en pekare till arrayens första element) int a[4] = {91, -2, 85, 17; int* p = a; // p = &a[0]; p[1] = 5; // a[1] = 5; p++; // p = &a[1]; cout << *p << endl; // 5 *(p + 2) = 26; // a[3] = 26; cout << p[2] << endl; // 26 2

9.7 Skräppekare Om de är oinitierade pekar pekare på godtyckliga platser i minnet. Om vi följer en sådan pekare kraschar antagligen programmet! int x = 42; int* p; cout << p << endl; cout << *p << endl; int a[3] = {91, -2, 85; int* p2 = a; cout << p2[5] << endl; // lagrar skräp // 0xd34d00 // KABOOM // BOOM 9.8 nullptr nullptr: Pekarliteral som betyder pekar på ingenting Tänkt att användas som ett tomvärde att initera pekare med Att avreferera en tompekare kraschar programmet! int x = 42; int* p = nullptr; cout << p << endl; // 0 cout << *p << endl; // KABOOM // testa för tomhet if (p == nullptr) {... // true 9.9 3

1.3 Objekt Pekare till objekt Vi kan peka på objekt För att referera till medlemmar i objektet, skriv object->member Samma sak som (*object).member Date d(9, 19); Date* p = &d; cout << p->daysinmonth() << endl; // 30 p->nextday(); cout << *p << endl; // 20/9 9.10 Objekts livstid Deklarerade objekt lever till slutet av nuvarande funktions definitionsområde Detta kallas statisk allokering eller allokering på stacken Om vi returnerar ett objekt kopieras det; originalet förstörs fortfarande Hur tillverkar vi ett objekt som överlever funktionen det skapas i? void foo() { int x = 42; Date d1(9, 19);... // x, d1 förstörs int main() { int a = 17; foo(); Date d2(10, 14);... return 0; // a, d2 förstörs 9.11 Dynamisk allokering Operatorn new allokerar långtidsminne för ett objekt Kallas dynamisk allokering eller allokering på heapen Låter objektet leva även efter funktionens definitionsområde tagit slut Minne för objekt allokerade på heapen måste frigöras explicit med delete void foo() { Date* d = new Date(10, 14); cout << d->daysinmonth() << endl; // 31 d->nextday(); cout << d << endl; // 0x3a67f4 cout << *d << endl; // 15/10... delete d; 9.12 4

1.4 Länkade noder Datastruktur för länkade noder struct ListNode { int data; ListNode* next; ; Varje listnodsobjekt lagrar: ett heltalsvärde en pekare till en listnod Listnoder kan länkas samman i kedjor för att lagra en lista av värden 9.13 Listnodsklient int main() { ListNode* list = new ListNode(); list->data = 42; list->next = new ListNode(); list->next->data = -3; list->next->next = new ListNode(); list->next->next->data = 17; list->next->next->next = nullptr; cout << list->data << " " << list->next->data << " " << list->next->next->data << endl; // 42-3 17... return 0; 9.14 Länkade noder: problem 1 Vilken sekvens av operationer omvandlar den här bilden: Till den här bilden? 9.15 Länkade noder: problem 2 Vilken sekvens av operationer omvandlar den här bilden: Till den här bilden? 9.16 5

Länkade noder: problem 3 Vilken sekvens av operationer omvandlar den här bilden: Till den här bilden? 9.17 Länkade noder: problem 4 Vilken sekvens av operationer omvandlar den här bilden: Till den här bilden? 9.18 Länkade noder: problem 5 Antag att vi har en lång kedja av listnoder ListNode* list = new ListNode(10); list->next = new ListNode(20); list->next->next =...; Vi vet inte exakt hur lång kedjan är Hur gör vi för att skriva ut datavärdena i alla noder? 9.19 Traversera en lista? Ett (dåligt) sätt att skriva ut alla värden i listan: while (list!= nullptr) { cout << list->data << endl; list = list->next; // flytta till nästa nod Vad är problemet med att göra på det här sättet? Vi tappar bort listan samtidigt som vi skriver ut den! 9.20 6

Listtraversering Rätt sätt att skriva ut alla värden i listan: ListNode* current = list; while (current!= nullptr) { cout << current->data << endl; current = current->next; // flytta till nästa nod Att ändra current skadar inte listan 9.21 2 Länkade listor LinkedList Låt oss skriva en containerklass LinkedList Har samma medlemmar som ArrayList add, clear, get, insert, isempty, remove, size, tostring Listan representeras internt som en kedja av länkade noder Listan har en pekare till den första noden i listan nullptr signalerar slutet av listan; är första noden nullptr är listan tom 9.22 LinkedList.h class LinkedList { public: LinkedList(); ~LinkedList(); void add(int value); void clear(); int get(int index) const; void insert(int index, int value); bool isempty() const; void remove(int index); void set(int index, int value); int size() const; string tostring() const; private: int m_size; ListNode* m_front; ; 9.23 7

Implementera add // Appends the given value to the end of the list. void LinkedList::add(int value) {... Hur adderar vi en ny nod till slutet av listan? Spelar listans innehåll innan operation någon roll? 9.24 Add på en tom lista Före add(20): Efter: 9.25 Add på en icke-tom lista Före add(20) Efter add(20) 9.26 Kod för add // Adds the given value to the end of the list. void LinkedList::add(int value) { if (m_front == nullptr) { // adding to an empty list m_front = new ListNode(value); else { // adding to the end of an existing list ListNode* current = m_front; while (current->next!= nullptr) { current = current->next; current->next = new ListNode(value); 9.27 8

Kod för get // Returns value in list at given index. // Precondition: 0 <= index < size() int LinkedList::get(int index) { ListNode* current = m_front; for (int i = 0; i < index; i++) { current = current->next; return current->data; Kod för insert // Inserts the given value at the given index. // Precondition: 0 <= index <= size() void LinkedList::insert(int index, int value) { if (index == 0) { // inserting at front of list m_front = new ListNode(value, m_front); else { // inserting in general position in list ListNode* current = m_front; for (int i = 0; i < index - 1; i++) { current = current->next; current->next = new ListNode(value, current->next); 9.28 9.29 Implementera remove // Removes value at given index from list. // Precondition: 0 <= index < size void LinkedList::remove(int index) {... Hur tar vi bort en nod från en given position i listan? Spelar listans innehåll innan operation någon roll? 9.30 Remove på en lista Före borttagning av elementet på index 1: Efter: 9.31 9

Remove i början av en lista Före borttagning av elementet på index 0: Efter: 9.32 Remove då det bara finns ett element Före: Efter: Vi måste ändra front till att lagra nullptr istället för en nod Behöver vi ett specialfall för att hantera detta? 9.33 Kod för remove // Removes value at given index from list. // Precondition: 0 <= index < size() void LinkedList::remove(int index) { ListNode* trash; if (index == 0) { // removing first element trash = m_front; m_front = m_front->next; else { // removing elsewhere in the list ListNode* current = m_front; for (int i = 0; i < index - 1; i++) { current = current->next; trash = current->next; current->next = current->next->next; delete trash; 9.34 10