23. oktober 2003 - 18:24Der er
43 kommentarer og 1 løsning
C: Splittelse af linked list i to
Hej,
Jeg er stødt ind i (endnu) et problem ved brugen af linked list.
Jeg skal have sorteret min liste, og det har jeg fundet ud af at gøre (håber og tror jeg), men før jeg kan gøre det er jeg nødt til at dele min linkede liste op i to. En liste der indeholder det første element i den originale liste og en anden liste der indeholder de resterende elementer fra den originale liste.
Jeg har forsøgt mig frem og tilbage med i funktionen orderlist, men lige langt kommer jeg. Det ender hele tiden med at programmet crasher så snart jeg prøver at udskrive listen med de resterende elementer. Listen med det første element i den nye liste ser ud til at virke, men som sagt ikke den anden.
I stedet for en løsning af fejlen ville jeg blive glad hvis nogle kunne guide mig på rette vej, men hvis jeg er helt ude i hampen med mit forslag er en løsning selvfølgelig også helt i orden :)
Jeg er godt klar over at jeg slet ikke behøver en linked liste, men det er nu engang den måde jeg vil gøre det på :)
Herunder er koden:
#include<stdio.h> #include<stdlib.h>
struct node{ char* name; int grade; struct node* next; };
/* head contains the first element from the original linked list remaining contains the rest of the list */ Node *head=NULL, *remaining, *first=NULL; int i = 0, headlistlength;
printf("Order list in increasing order\n");
// Split list in two while (node != NULL){ if (i == 0){ head = (Node*)malloc(sizeof(Node)); head->name = node->name; head->grade = node->grade; head->next = NULL; } else { remaining = (Node*)malloc(sizeof(node)); if (i == 1) first = remaining; remaining->name = node->name; remaining->grade = node->grade; } node = node->next; i++; }
/* head contains the first element from the original linked list remaining contains the rest of the list */ Node *head=NULL, *remaining, *first=NULL, *parent=NULL; int i = 0, headlistlength;
printf("Order list in increasing order\n");
// Split list in two while (node != NULL){ if (i == 0){ head = (Node*)malloc(sizeof(Node)); head->name = node->name; head->grade = node->grade; head->next = NULL; } else { remaining = (Node*)malloc(sizeof(node)); if (i == 1) first = remaining; remaining->name = node->name; remaining->grade = node->grade; remaining->next = NULL; if(parent != NULL) parent->next = remaining; parent = remaining; } node = node->next; i++; }
Jeg har pastet det ind du postede og får føromtalte fejl.
Den når lige at skrive linien printf("Order list in increasing order\n"); ud og så er der dømt Application Error.
Hvis jeg derimod fjerner remaining->next = NULL; kan den udskrive listen, men kun én gang. Hvis jeg vælger at sortere listen igen, udskriver den også listen, men jeg får denne fejl før den springer ud af orderlist funktionen:
Hmm, hvis jeg istedet for at køre den inde fra Dev-C++ (ved at trykke F9 - Compile & Run) kører den fra en dosprompt kan den godt udskrive listen, men kun to gange.
Hvis jeg tager remaining->next = NULL; med, får jeg samme output som dig, men kan kun se listen én gang. Hvis jeg vil se den igen får jeg en application error.
Jeg kan hverken se listen fra en dos prompt eller dev-c++, der får jeg en application error. Det "virker" kun når jeg dobbeltklikker på .exe filen.
Vildt gæt ... Students arrayet er defineret inde i start list funktionen. Arrayet bliver allokeret på stack'en - ikke på en heap. Dvs. når du initializerer de enkelte nodes sætter du "node->name" til et navn der er allokeret på stacken. Når funktionen exiter umyndiggøres arrayet på stacken. Navnene bliver derved overskrevet når de andre funktioner bruger stacken. Der er umiddelbart to måder at løse det på.
1) Erklær arrayet som "static" (static Node student[10]={ ... })
2) Flyt Node student array'et ud som et globalt array - altså, ud af funktionen.
Med hensyn til stack/heap så er students ganske vist allokeret på stak men jeg vil formode at streng konstanterne er allokeret i heap - og det er jo kun dem vi bevarer hen over kald.
Btw, i funktionen makestartlist som du hjalp mig med at lave er følgende to linier:
if (i>0) parent -> next = node; parent = node;
Uden dem virker den ikke som den skal, men jeg kan ikke se hvorfor de skal være der, parent bliver jo ikke brugt til noget nogen steder. Kan du forklare det?
Det er de linier som sørger for at next peger på næste element.
if(i>0) hvis ikke første (d.v.s. at der er en foregående) parent -> next = node; sæt foregående's next til at pege på nuværende parent = node; sæt foregående til nuværende (for næste gennemløb)
Jeg fik vist formuleret mig lidt dårligt. Jeg forstår godt logikken i det, men jeg kan ikke se hvorfor parent bruges, for de to linier ændrer jo kun på hvad parent peger på og har ingen betydning for hvad node peger på.
Skal det forstås sådan at uden de to linier ville man ikke kunne "pushe" et nyt element ind foran det man netop har indsat?
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.