C-programmering ID120V William Sandqvist Länkad lista
Länkad lista William Sandqvist Data (i primärminnet) som en länkad lista datatypen för varje element i listan är en struktur, post ( struct )
Tänk om arrayen Komplex z[?]; inte är tillräcklig? William Sandqvist Komplex z Problemet med Komplex z[?] är att storleken måste bestämmas när man skriver programmet inte när det körs. De medel som står tillbuds, tills nu, är att allokera upp minne på heapen m h a malloc() eller calloc() ( continous ). Funktionen ger konsekutivt minne på heapen som kan behandlas som en array. Dock måste allt minne allokeras på en gång.
malloc( ) och calloc() William Sandqvist Stack Bytes Heap Stack Heap Stack Heap Att indexera fungerar bra, z[3] Att indexera fungerar inte, z[3] z[3] Att indexera fungerar bra, z[3] Att utöka en ”array” genom succesiva allokeringar går inte så bra, minnet ”hänger” inte ihop. calloc() malloc() har använts en gång calloc() malloc() har använts flera gånger länkad lista, posterna hänger ihop med pekare
Tänk om arrayen Komplex z[?]; inte är tillräcklig? William Sandqvist Komplex z allokera dynamiskt en struct ( ett komplext tal ) i taget och håll ihop dem med en länk ( = pekare ) till en länkad lista. Detta löser problemet!
Länkad lista William Sandqvist inget = null re im pekare re im pekare re im pekare re im pekare Den nya strukturen, posten allokera dynamiskt en "tunna" i taget efter behov låt föregående "tunna" peka ut nästa för att hålla ihop data
Länkad lista William Sandqvist inget = null re im pekare re im pekare re im pekare re im pekare typedefstruct Komplex{ floatre; /* realdel */ float im; /* Imaginärdel */ struct Komplex*nextPek; /* pekare till nästa */ } Komplex ; Eftersom strukturen skall referera till sig själv så måste definitionen se ut på detta sätt. strukturen
Hur skapas en ”länkad lista” ? William Sandqvist main() inget = null re im pekare re im pekare re im pekare re im pekare Det behövs en pekare till första posten! zListPek Denna funktion skapar listan int main ( void ) { Komplex* zListPek ; zListPek = LaesKomplexaTalLista(); SkrivKomplexTalLista( zListPek ); FreeMemory( zListPek ); return 0 ; }
linklist.c William Sandqvist /* linklist.c länkad lista med struct av komplexa tal */ #include #include typedef struct Komplex { float re; /* realdel */ float im; /* Imaginärdel */ struct Komplex * nextPek; /* pekare till nästa i listan */ } Komplex ; Komplex* LaesKomplexaTalLista( void ); void SkrivKomplexTalLista( Komplex * zListPek ); void FreeMemory( Komplex * zListPek );
main() William Sandqvist int main(int argc, char *argv[]) { Komplex * zListPek ; zListPek = LaesKomplexaTalLista(); SkrivKomplexTalLista( zListPek ); FreeMemory( zListPek ); printf("\n"); system("PAUSE"); return 0; }
LaesKomplexaTalLista(void); William Sandqvist Komplex * LaesKomplexaTalLista( void ) { char avslutandeTecken = ' '; Komplex * huvudPek = NULL, * svansPek ; huvudPek = (Komplex *)malloc(sizeof( Komplex )); printf("\nAvsluta med * efter sista talet --> 2 3* !"); printf("\nGe real och imagin\204rdel --> "); scanf("%f%f%c", &huvudPek->re, &huvudPek->im, &avslutandeTecken ); /* vid första inmatningen är huvudet också svans */ svansPek = huvudPek;...
LaesKomplexaTalLista(void); William Sandqvist while ( avslutandeTecken != '*' ) { svansPek->nextPek=(Komplex*)malloc(sizeof(Komplex )); svansPek = svansPek->nextPek; printf("\nAvsluta med * efter sista talet 2 3* !"); printf("\nGe real och imagin\204rdel --> "); scanf("%f%f%c", &svansPek->re, &svansPek->im, &avslutandeTecken); svansPek->nextPek = NULL; } return huvudPek ; }... ytterligare ett element har lagts till ett element har lagts till
LaesKomplexaTalLista(void); William Sandqvist return huvudPek ; svansPek->nextPek=(Komplex*)malloc(sizeof(Komplex )); ny post ny svans svansPek = svansPek->nextPek; inmatning scanf("%f%f%c", &svansPek->re, &svansPek->im, &avslutandeTecken); sista peka på NULL svansPek->nextPek = NULL; ( returnera huvud/svans )
SkrivKomplexTalLista(); William Sandqvist void SkrivKomplexTalLista( Komplex * zlistPek ) { Komplex *current = zListPek; /* Börja med huvudet */ printf("\n"); while(current != NULL) { printf("%f %fi\n", current->re, current->im); current = current->nextPek; /* Gå vidare till nästa element */ } }
FreeMemory() William Sandqvist while(!NULL) next = current->nextPek current = next free(current) Man kan inte ta bort ett element förrän man sparat undan dess next-pekare!
FreeMemory() William Sandqvist void FreeMemory( Komplex * zListPek) { Komplex *current = zListPek; /* Börja med huvudet */ Komplex * next ; while(current != NULL) { next = current->nextPek; /* Såga aldrig av den gren du sitter på */ free(current); /* Strukten tas bort inklusive nextPek! */ current = next; /* Gå vidare till nästa element */ } }
William Sandqvist Länkad lista i minnet En länkad lista lagras inte sammanhängande i minnet Den här listan kan man inte sortera med Quicksort!
Sortera index William Sandqvist Man sorterar inte länkade listor. Däremot behöver man kunna sortera vilken ordning man vill bearbeta, eller skriva ut, posterna. Inför en sådan uppgift kan man lagra pekarna till posterna i en array (indexarray). Då kan pekarna sorteras utan att posterna behöver flyttas i minnet. Sorteringsfunktionen använder pekarna tillsammans med piloperatorn -> för att nå valfri delpost att sortera utifrån.
Hur sorterar man elefanter? Genom att sortera pekarna – inte gärna genom att flytta på elefanterna! William Sandqvist
Långsamt! Snabbt! NULL