Lineaire data structuren. Doorlopen van een lijst

Vergelijkbare documenten
Recursie: definitie. De som van de kwadraten van de getallen tussen m en n kan als volgt gedefinieerd worden:

Dynamisch geheugen beheer

Datastructuren: stapels, rijen en binaire bomen

Tentamen Programmeren in C (EE1400)

Examen Programmeren 2e Bachelor Elektrotechniek en Computerwetenschappen Faculteit Ingenieurswetenschappen Academiejaar juni, 2010

EE1400: Programmeren in C BSc. EE, 1e jaar, , 4e college

Tentamen Programmeren in C (EE1400)

Datastructuren: stapels, rijen en binaire bomen

Tentamen Programmeren in C (EE1400)

EE1400: Programmeren in C BSc. EE, 1e jaar, , 3e college

Programmeren in C++ Efficiënte zoekfunctie in een boek

Programmeermethoden. Pointers. Walter Kosters. week 10: november kosterswa/pm/

Programmeermethoden. Functies vervolg. Walter Kosters. week 5: 1 5 oktober kosterswa/pm/

Tree traversal. Bomen zijn overal. Ferd van Odenhoven. 15 november 2011

Een eenvoudig algoritme om permutaties te genereren

Stacks and queues. Hoofdstuk 6

Een gelinkte lijst in C#

Tree traversal. Ferd van Odenhoven. 15 november Fontys Hogeschool voor Techniek en Logistiek Venlo Software Engineering. Doorlopen van bomen

Arrays. Complexe datastructuren. Waarom arrays. Geen stijlvol programma:

Universiteit van Amsterdam FNWI. Voorbeeld van tussentoets Inleiding programmeren

De MySQL C API. Variabelen in C Functies in C Pointers in C

De doorsnede van twee verzamelingen vinden

12 Meer over pointers

P R O G R A M M E E R - T E C H N I E K E N

Programmeermethoden. Recursie. week 11: november kosterswa/pm/

Uitwerking tentamen Algoritmiek 9 juli :00 13:00

9 Meer over datatypen

Modelleren en Programmeren

Datastructuren Werkcollege Intro

Voorbeeldtentamen Inleiding programmeren (IN1608WI), Oktober 2003, , Technische Universiteit Delft, Faculteit EWI, Afdeling 2.

recursie Hoofdstuk 5 Studeeraanwijzingen De studielast van deze leereenheid bedraagt circa 6 uur. Terminologie

De doorsnede van twee verzamelingen vinden

Vakgroep CW KAHO Sint-Lieven

Algoritmiek. 15 februari Grafen en bomen

Tweede college algoritmiek. 12 februari Grafen en bomen

NAAM: Programmeren 1 Examen 29/08/2012

Recursion. Introductie 37. Leerkern 37. Terugkoppeling 40. Uitwerking van de opgaven 40

int getaantalpassagiers{): void setaantalpassagiers(int aantalpassagiers);

10 Meer over functies

Elementary Data Structures 3

Javascript oefenblad 1

HOGESCHOOL VAN AMSTERDAM Informatica Opleiding. CPP 1 van 10

Java Programma structuur

Week 5 : Hoofdstuk 11+ extra stof: meer over functies. Hoofdstuk 11:

continue in een for, while of do lus herhaalt de lus vroegtijdig. De volgende herhaling wordt onmiddellijk begonnen.

Programmeren (1) Examen NAAM:

Opgaven Abstracte Datastructuren Datastructuren, Werkgroep, 31 mei 2017.

Programmeermethoden. Recursie. Walter Kosters. week 11: november kosterswa/pm/

7 Omzetten van Recursieve naar Iteratieve Algoritmen

Uitwerking Tweede deeltentamen Imperatief programmeren - versie 1 Vrijdag 21 oktober 2016, uur

Auteur Inleiding Namen in applicatie Opslag structuur Gedefinieerde structuren... 4

int main() { int m; m = power(2,3) /* berekent 2^3 en geeft de resultaat naar m terug */ }

Achtste college algoritmiek. 8 april Dynamisch Programmeren

Uitwerkingen derde deeltentamen Gameprogrammeren Vrijdag 6 november 2015, uur

Oefententamen 2. Tijd: 2 uur. Maximaal aantal punten: 30. Naam: Studentnummer:

Dynamisch Programmeren. Het Rugzakprobleem

Instructies en blokken

Programmeertechnieken

Een typisch programma in C en C++ bestaat uit een aantal onderdelen:

TENTAMEN Programmeren 1 VOORBEELDUITWERKING

17 Operaties op bits Bitoperatoren en bitexpressies

Modelleren en Programmeren


Online c++ leren programmeren:

Datastructuren Uitwerking jan

Examen Programmeren 2e Bachelor Elektrotechniek en Computerwetenschappen Faculteit Ingenieurswetenschappen Academiejaar juni, 2010

Computervaardigheden. Universiteit Antwerpen. Computervaardigheden en Programmatie. Grafieken en Rapporten 1. Inhoud. Wat is scripting?

voegtoe: eerst methode bevat gebruiken, alleen toevoegen als bevat() false is

Hoofdstuk 3. Week 5: Sorteren. 3.1 Inleiding

Datastructuren en algoritmen

Transcriptie:

Lineaire data structuren array: vast aantal data items die aaneensluitend gestockeerd zijn de elementen zijn bereikbaar via een index lijst: een aantal individuele elementen die met elkaar gelinkt zijn deze links geven de volgorde in de lijst aan Een bepaald element in de lijst kan alleen aangesproken worden vanuit het voorgaande element. Er zijn twee voordelen: B F L + de lengte van de lijst kan veranderen tijdens de levensduur: men kan gemakkelijk elementen toevoegen en/of verwijderen; + de flexibiliteit om de elementen te herschikken in een andere volgorde. Doorlopen van een lijst De lijst sequentieel doorlopen kan met een eenvoudige while lus: void doorloop ( Node p) while ( p!= ( Node )NULL ) printf ( %c, p >data ) ; p = p >volgend ; printf ( \n ) ; Een mogelijke oproep is doorloop();. Een knooppunt van een lijst bevat twee delen: de informatie (van type Info) en een link naar de volgende node. typedef struct snode Info data ; Node ; struct snode volgend ; Voorbeeld: data is van het type char (typedef char Info;) veld volgend : pointer naar het volgende element op de lijst aangeven hoe het eerste element van de lijst kan bereikt worden via een extra variabele, (type is Node *) aangeven dat een bepaald element het laatste element is volgend veld vh laatste element gelijkstellen aan (Node *)NULL. B F L Een lijst construeren : telkens een element vooraan toevoegen: Node voegvooraantoe (Node, Info gegeven ) Node nieuw ; nieuw = (Node ) malloc ( sizeof (Node ) ) ; nieuw >data = gegeven ; nieuw >volgend = ; return nieuw ; Bovenstaande lijst wordt geconstrueerd door volgende oproepen: Node = ( Node )NULL; = voegvooraantoe (, ) = voegvooraantoe (, L ) = voegvooraantoe (, F ) = voegvooraantoe (, B )

Het zoeken van een element met waarde gegeven in de gelinkte lijst vanaf knooppunt : Iteratief: Node zoek (Node, Info gegeven ) Node p ; p = ; while ( p!= ( Node )NULL ) i f ( p >data == gegeven ) return(p ) ; p = p >volgend ; Het omkeren van de volgorde in de gelinkte lijst: B F L Node omkeren ( Node ) Node p, q, r ; p = ; r = (Node )NULL; while ( p!= ( Node )NULL ) q = p ; return r ; p = p >volgend ; q >volgend = r ; r = q ; Recursief: Node rzoek (Node p, Info gegeven ) if ( p == (Node )NULL ) return(p ) ; i f ( p >data == gegeven ) return(p ) ; return rzoek ( p >volgend, gegeven ) ; Oproep in beide gevallen: Node v = ( r ) zoek (, ) ; Operaties: toevoegen Het toevoegen van een nieuw element na knooppunt na: Node voegtoe (Node na, Info gegeven ) Node nieuw ; nieuw = (Node ) malloc ( sizeof (Node ) ) ; nieuw >data = gegeven ; i f ( na!= ( Node )NULL ) nieuw >volgend = na >volgend ; na >volgend = nieuw else nieuw >volgend = ( Node )NULL; return nieuw ;

B F L J na >volgend = q >volgend ; free (q ) ; return na ; Mogelijke oproep: if (==NULL) =voegtoe (NULL, g) else voegtoe (na, g ) ; B F L Een oproep zou kunnen zijn: x->volgend = verwijder(x->volgend);. Operaties: verwijderen Het verwijderen van een element na knooppunt na: Node verwijder (Node na) Node q = na >volgend ; Het verwijderen van het laatste element: Hiervoor moet eerst het voorlaatste element bepaald worden. Node verwijderachteraan ( Node ) Node vorig, actueel ; if ( q == (Node )NULL ) /* er is geen volgend element */ /* een mogelijkheid is het element zelf verwjderen */ free (na ) ; /* pointer die na aanwijst is NIE aangepast in NULL!! */ else i f (!= ( Node )NULL ) i f ( >volgend == ( Node )NULL ) fr ee ( ) ; else vorig = ;

actueel = >volgend ; while ( actu eel >volgend!= ( Node )NULL ) vorig = actueel ; actueel = actueel >volgend ; free ( actueel ) ; vorig >volgend = ( Node )NULL; return ; return ; p = p >volgend ; i f ( p >volgend!= twee ) /* er moet een element voor "twee" zitten */ p >volgend = twee >volgend ; twee >volgend = een >volgend ; een >volgend = twee ; Oefening. Wat gebeurt er als element twee reeds vlak na element een zit? Operatie herschikken Het herschikken van de lijst: element twee komt vlak achter element een: B Node herschik ( Node, Node een, Node twee ) Node p = ; if ( p == (Node )NULL ) F while ( p >volgend!= ( Node )NULL ) i f ( p >volgend == twee ) break ; L Dubbel gelinkte lijsten + gelinkte lijst: het volgend element kan gemakkelijk gevonden worden + vorige element vinden : gans de lijst moet tot aan het element doorzocht worden + dit efficiënter doen: gebruik maken van een dubbel gelinkte lijst: naast een verwijzing naar het volgende element op de lijst is ook een verwijzing naar het vorige element aanwezig. typedef struct dub Info data ; struct dub volgend ; struct dub vorig ; Dnode;

B F L herschik functie: voorgaande element van twee moet niet gezocht worden: Dnode herschik ( Dnode een, Dnode twee ) twee >vorig >volgend = twee >volgend ; twee >volgend >vorig = twee >vorig ; twee >volgend = een >volgend ; twee >vorig = een ; een >volgend >vorig = twee ; een >volgend = twee ; Het probleem van Josephus: Veronderstel dat N mensen besloten hebben om collektief zelfmoord te plegen door in een cirkel te gaan staan en telkens de M-e persoon te elimineren. Wie blijft er over of wat is de volgorde van afvallen? Bijvoorbeeld bij N = 7 personen met M = 4 is de volgorde: 4 1 6 5 7 3 2. /* * telaf.c : het probleem van Josephus : met een lijst */ #include <stdio. h> #include <malloc. h> #define MAXP 25 int a f t e l l e n ( int n, int m) ; int main( int argc, char argv [ ] ) int n, m, res ; Circulaire lijsten Voorgaande functie is correct wanneer na een nog minstens één element aanwezig is en wanneer voor en na twee ook minstens één element aanwezig is. Om deze voorwaarden niet te hoeven controleren kunnen we een circulaire lijst gebruiken. Wanneer het laatste element in de lijst wijst naar het eerste element, heeft men een circulaire lijst: 1 2 3 4 5 6 7 t printf ( Aantal mensen : ) ; scanf ( %d% c, &n ) ; printf ( Hoeveel overslaan : ) ; scanf ( %d% c, &m) ; res = a f t e l l e n (n, m) ; printf ( De laatste van %d met %d overslaan : %d\n, n, m, res ) ; typedef struct node int nr ; struct node next ; Elem ; void drukaf (Elem x ) ; int a f t e l l e n ( int n, int m)

Elem v ; Elem t ; /* wijst naar persoon die revolver net heeft doorgegeven */ int i ; v = t = (Elem ) malloc ( sizeof (Elem) ) ; v >nr = 1; for ( i =2; i<=n ; i++) v >next = (Elem ) malloc ( sizeof (Elem) ) ; v = v >next ; v >nr = i ; v >next = t ; t = v ; drukaf ( t ) ; while ( t!= t >next ) printf ( %3d, t >nr ) ; t = t >next ; while ( t!= x ) ; printf ( \n ) ; for ( i =1; i<m; i++) t = t >next ; v = t >next ; t >next = t >next >next ; free (v ) ; drukaf ( t ) ; return t >nr ; void drukaf ( Elem x) Elem t ; t = x ; do Stacks In veel toepassingen is het niet nodig om op een willekeurige plaats in de lijst elementen te kunnen toevoegen of verwijderen. Ook het herschikken van de elementen in de lijst is niet altijd vereist. Een stack is een data-structuur waarop slechts twee mogelijke operaties gedefinieerd zijn: push : het toevoegen van een element in het begin van de lijst; pop : het verwijderen van het eerste element van de lijst. Een klassiek voorbeeld is het berekenen van de waarde van een eenvoudige rekenkundige uitdrukking. De intermediaire resultaten kunnen gemakkelijk op een stack bewaard worden.

De waarde van 5 (((9 + 8) (4 6)) + 7) kan berekend worden met push(5); push(9); push(8); push( pop() + pop() ); push(4); 6 push(6); 8 4 24 7 push( pop() * pop() ); 9 17 17 17 408 415 push( pop() * pop() ); push(7); push( pop() + pop() ); push( pop() * pop() ); printf( "%d\n", pop() ); 5 5 5 5 5 5 2075 int isstackle eg (void ) return! top ; int isstackvol (void ) return top==max; + variabele top : de index van de eerste vrije plaats, de plaats waar een volgend element kan gepusht worden. + in deze eenvoudige functies wordt NIE nagegaan wordt of de array volzet is (bij een push) of de array leeg is (bij een pop) Oefening. Implementeer deze stack functies met behulp van een gelinkte lijst. Wanneer de maximale lengte van de stack op voorhand gekend is, kan bij de implementatie gebruik gemaakt worden van een array: #define MAX 100 static int stack [MAX] ; static int top ; void s tackinit (void ) top = 0; /* top wijst naar eerstvolgende vrije element */ void push ( int w) stack [ top++] = w; int pop(void ) return stack[ top ] ; Queues Bij een queue zijn er ook maar twee basisoperaties mogelijk: + toevoegen van een element aan de ene kant van de lijst, + wegnemen van een element aan de andere kant. Een implementatie met behulp van een array: #define MAX 100 static int queue [MAX] ; static int ; static int staart ; void queueinit (void ) staart = = 0; void put( int w)

queue [ staart ++] = w; /* staart wijst naar lege plaats */ if ( staart == MAX ) /* waar eerstvolgende element */ staart = 0; /* moet toegevoegd worden */ int get (void ) int w = queue [ ++]; /* wijst naar eerste element */ i f ( == MAX ) /* dat kan weggenomen worden */ = 0; return w; int isqueueleeg (void ) return ==staart ; Denktaak Veronderstel dat top een pointer is naar het eerste element van een dubbel gelinkte lijst. Zo n element is van type Stack. Wat is het effect van de functieoproep top = functie(top);? Verklaar uw antwoord met een tekening. typedef struct node int waarde ; struct node volgend ; struct node vorig ; Stack ; Stack functie ( Stack top ) Stack p = top ; Stack t ; Oefening. Implementeer deze queue functies met behulp van een dubbel gelinkte lijst. staart K N I P Stack v = top ; while ( p!= NULL ) t = p >volgend ; p >volgend = p >vorig ; p >vorig = t ; v = p ; p = t ; return v ;