Länkade listor i C Länkade listor kan ingå som en del av språket, dock ej i C Länkade listor är ett alternativ till: Dynamiskt allokerad array Arrayer allokerade på stacken Kan alltså användas till att lagra en lista av data som representerar ett antal saker Använder dynamiskt minne 1
Länkad lista vs array Borttagning/insättning av element på viss (valfri) plats Länkad lista: effektiv Array: ineffektiv (elementen efter måste flyttas efter) Returnera ett element på plats med visst (valfritt) index. Länkad lista: Ineffektiv, måste loopa fram till platsen (och räkna under tiden) Array: Effektivt I många tillämpningar uppstår aldrig behovet att veta vad som finns på ett visst index 2
Länkade listor I en länkad lista ligger inte elementen nödvändigtvis i en följd i minnet. Elementen i länkade listan består av Datainnehållet, dvs det som man vill lagra (fortsättningsvis låtsas vi att det är en int som vi vill lagra, men det kan vara vilken datatyp som helst) Pekare till nästa element Eventuellt en pekare till förra elementet Annat som behövs... 3
Länkade listor, exempel En lista med 3 element: 4
Länkade listor, exempel En lista med 3 element: Pekare till början av listan Ett element Stoppmarkering i det sista elementets nextpekare Det blå är datat Pekare från ett element till nästa 5
Insättning En operation som man kan behöva på en länkad lista är att sätta in ett data sist. Vi antar först tom lista, dvs anropet av ListInsertLast(List *list, int data); Ser ut: ListInsertLast(, ); 6
Insättning Kopia av anroparens pekare till listan Kopia av anroparens data ListInsertLast(, ); Algoritmen, stegvis: Input : 7
Insättning Algoritmen, stegvis: Skapa ett Element (kallas ofta nod) Ett element (dynamiskt allokerat) Tillfällig pekare: 8
Insättning Algoritmen, stegvis: Skapa ett Element (kallas ofta nod) Sätt in datat i elementet Tom länk (NULL-pekare) 9
Insättning Algoritmen, stegvis: Skapa ett Element (kallas ofta nod) Sätt in datat i elementet Sätt listan att peka på elementet 10
Insättning Algoritmen, stegvis: Skapa ett Element (kallas ofta nod) Sätt in datat i elementet Sätt listan att peka på elementet Nu har vi en komplett lista med ett element Hur ska anroparen få glädje av den? - Returvärde! 11
Insättning Vi antar nu icke-tom lista, dvs anropet ListInsertLast(, );... 12
Insättning, algoritm Data att sätta in... 13
Insättning, algoritm Skapa Element och sätt in datat (som tidigare)... Tillf. Pekare till allokerat element. Data insatt i elementet 14
Insättning, algoritm Skapa Element och sätt in datat (som tidigare) Skaffa en en pekare för att iterera... Annan tillf. pekare 15
Insättning, algoritm Skapa Element och sätt in datat (som tidigare) Skaffa en en pekare för att iterera Sätt den att peka på första elementet... 16
Insättning, algoritm Skapa Element och sätt in datat (som tidigare) Skaffa en en pekare för att iterera Sätt den att peka på första elementet Nu når vi till nästa pil, ta den istället... 17
Insättning, algoritm Skapa Element och sätt in datat (som tidigare) Skaffa en en pekare för att iterera Sätt den att peka på första elementet Nu når vi till nästa pil, ta den istället... 18
Insättning, algoritm Skapa Element och sätt in datat (som tidigare) Skaffa en en pekare för att iterera Sätt den att peka på första elementet Nu når vi till nästa pil, ta den istället Upprepa tills det inte finns någon mer pil... 19
Insättning, algoritm Skapa Element och sätt in datat (som tidigare) Skaffa en en pekare för att iterera Sätt den att peka på första elementet Nu når vi till nästa pil, ta den istället Upprepa tills det inte finns någon mer pil... 20
Insättning, algoritm Skapa Element och sätt in datat (som tidigare) Skaffa en en pekare för att iterera Sätt den att peka på första elementet Nu når vi till nästa pil, ta den istället Upprepa tills det inte finns någon mer pil Sätt in en pekare där som det inte finns någon så att den pekar på det nya elementet... 21
Insättning, algoritm Skapa Element och sätt in datat (som tidigare) Skaffa en en pekare för att iterera Sätt den att peka på första elementet Nu når vi till nästa pil, ta den istället Upprepa tills det inte finns någon mer pil Sätt in en pekare där som det inte finns någon så att den pekar på det nya elementet... 22
Insättning, algoritm Skapa Element och sätt in datat (som tidigare) Skaffa en en pekare för att iterera Sätt den att peka på första elementet Nu når vi till nästa pil, ta den istället Upprepa tills det inte finns någon mer pil Sätt in en pekare där som det inte finns någon så att den pekar på det nya elementet... Allt klart bara att returnera huvudpekaren 23
C-kod typedef struct Element Element; struct Element { Element *next; int data;}; Element *ListInsertLast(Element *e, int x) { Element *p=e,*ne=malloc(sizeof(element)); if (ne) { ne >data = x; ne >next = NULL; if (e) { while (p >next) p = p >next; p >next = ne; } else e = ne; } return e; } 24
övning Skriv om föregående kodexempel så att det blir två funktioner: En för fallet att det ännu inte finns någon lista: Element *ListCreateFirst(int x); En annan för fallet att det redan finns element: void ListExtend(Element *e, int x); Skriv slutligen om originalfunktionen så att den använder de två du nyss gjort Fundera på vad som är bäst för användaren: använda olika eller wrappern 25
Hålla reda på slutet Det är onödigt att leta igenom hela listan för att hitta slutet Ett alternativ är att hålla reda på både slutet och början av listan Även andra saker som berör hela listan kan man vilja hålla reda på (ex. Antal element) Ofta lägger man alla sådana saker i en annan struct (som det bara finns en av). En sådan utgör en abstraktion av hela 26 listan
Användning Element *list; list = ListInsertLast(NULL, 42); ListInsertLast(list, 99); ListInsertLast(list, 3); ListInsertLast(list, 19); ListPrint(list); 27
Printfunktion på listan void ListPrintAll(Element *e) { while (e) { printf( %d\n, e >data); e = e >next; } } Eller rekursivt: void ListPrintAll(Element *e) { if (e) { printf( %d\n, e >data); ListPrintAll(e >next); } } 28
övning Skriv en mainfunktion som Låter användaren skriva in heltal tills Ctrl-D Vartefter heltalen skrivs in ska de länkas in sist en en länkad lista. När detta är klart ska listan skrivas ut 29