2016-03-21 37 views
0

yazdırmaya çalışırken çöküyor Bu yüzden bir program üzerinde çalışıyorum, sonunda ördek ördek kaz (aslında profesör tarafından ördek ördek önyükleme denir) bir gevşek sürümünü simüle edecek. Sorunu okurken dairesel bağlantılı liste bana doğru atılan şeydir. Genelde bağlantılı listeleri kullanmama rağmen çok yeni.Dairesel Bağlantılı liste

Program, düğümleri oluşturuyor ve ataıyor gibi görünüyor, ancak bunları yazdırmaya çalıştığımda çöküyorum.

#include <stdio.h> 
#include <stdlib.h> 

typedef struct { 
    char name[20]; 
    struct jimmysFriend *next; 
} jimmysFriend; 

jimmysFriend *createNode(); 
void populateList(jimmysFriend *bestFriend, int numberOfFriends); 
//void duckDuckBoot(); 
void printList(jimmysFriend *bestFriend); 

int main(void) { 
    int i; 
    int cases; 
    int numberOfFriends; 
    scanf("%d", &cases); 
    for (i = 0; i < cases; i++) { 
     scanf("%d", &numberOfFriends); 
     jimmysFriend *bestFriend; //head 
     bestFriend = NULL; 
     populateList(bestFriend, numberOfFriends); 
     printList(bestFriend); 
    } 
    return 0; 
} 

void populateList(jimmysFriend *bestFriend, int numberOfFriends) { 
    int i; //Where I actually create the circular list. 
    jimmysFriend *aFriend; 
    for (i = 0; i < numberOfFriends; i++) { 
     aFriend = createNode(); 
     if (bestFriend == NULL) { 
      bestFriend = aFriend; 
      aFriend->next = aFriend; 
     } else 
     if (bestFriend != NULL) { 
      jimmysFriend *temptr; 
      aFriend->next = bestFriend; 
      temptr = bestFriend; 
      while (temptr->next != bestFriend) { 
       temptr = temptr->next; 
      } 
      temptr->next = aFriend; 
     } 
    } 
} 

jimmysFriend *createNode() { //Creates a node 
    jimmysFriend *aFriend; 
    aFriend = malloc(sizeof(jimmysFriend)); 
    if (aFriend != NULL) { 
     scanf("%s", aFriend->name); 
    } 
    return aFriend; 
} 

void printList(jimmysFriend *bestFriend) { //Problem area? 
    jimmysFriend *temptr; 
    temptr = bestFriend; 
    while (temptr->next != bestFriend) { 
     printf("%s\n", temptr->name); 
     temptr = temptr->next; 
    } 
} 
+0

Bağlantılı listenin yalnızca 1 öğe içerdiği durumlardan biri bariz bir sorundur. Bu durumda, "populateList", "bestFriend = aFriend;" ve "aFriend-> next = aFriend;" öğelerini ayarlar. Bu, printList'deki 'while' döngüsünün hiçbir şey yazdırmadan biteceği anlamına gelir. Genel olarak, 'while' döngüsünün listeden daha az bir giriş basacağı görülmektedir. – user3386109

+0

@ user3386109 Söylediklerinizin ne anlama geldiğini görüyorum, sadece listenin yalnızca "printList" içinde bir öğe içerdiğini kontrol eden bir if ifadesi olması için iyi bir düzeltme olur mu? – Jude

+0

2 fark ettiğim şeyler: 1) 'typedef struct' ->' typedef struct jimmysFriends' 2) 'aFriend = malloc (sizeof (jimmysFriend));' -> aFriend = (jimmysFriend *) malloc (sizeof (jimmysFriend)); ' – DimChtz

cevap

2

2 tane sorun var.

Birincisi, bestFriend adresini populateList() adresine geçirmemenizdir, bu nedenle değişmez.

void populateList(jimmysFriend **bestFriend, int numberOfFriends){ 
    int i; //Where I actually create the circular list. 
    jimmysFriend* aFriend; 
    for(i = 0; i < numberOfFriends; i++){ 
     aFriend = createNode(); 
     if(*bestFriend == NULL){ 
      *bestFriend = aFriend; 
      aFriend->next = aFriend; 
     } 
     else if(*bestFriend != NULL){ 
      jimmysFriend* temptr; 
      aFriend->next = *bestFriend; 
      temptr = *bestFriend; 
      while(temptr->next != *bestFriend){ 
       temptr = temptr-> next; 
      } 
      temptr->next = aFriend; 
     } 
    } 
} 

Ve sonra şöyle diyoruz: populateList() gibi görünmelidir

populateList(&bestFriend, numberOfFriends); 

ikinci sorunu printList() döngü için koşul yanlış olmasıdır. Orada bunu yazma birden fazla yolu olduğunu, ancak bu do döngü çalışır:

void printList(jimmysFriend* bestFriend){ //Problem area? 
    if (bestFriend != NULL) { 
     jimmysFriend* temptr = bestFriend; 
     do { 
      printf("%s\n", temptr->name); 
      temptr = temptr->next; 
     } while (temptr != bestFriend); 
    } 
} 

Referans: Circular Linked List populateList() in

+0

Her zaman referansa bir işleve geçmenin orijinal değişkeni değiştirmeme izin vereceğini düşündüm. Öyleyse eğer orijinal değişkenim bir fonksiyondan yapılan değişiklikleri yapabilecek bir işaretçiyse, onu bir çift işaretçi yapmalıyım? Ayrıca neden döngü durumum yanlış? Aslında neyin yanlış olduğundan emin değilim. Ama önerileriniz işe yarıyor! Teşekkürler! – Jude

+0

Jude, @ döngüsünün neden çalışmadığını öğrenmek için @ user3386109'un yorumunu okudu. –

1

Jimmy'nin iyi arkadaşı gerçekten listenin başında işaret dahi sizi işlev ile yapılır. PopulateList() uygulamasında yaptığınız atama kaybolur.

Jimmy'nin en iyi arkadaşını işlevin işaretçisinin adresi olarak geçirin. Yani populateList() jimmysFriend ** bestFriend'i kabul eder. Sonra kafayı saklamaya çalıştığınızda, kafa olmak istediğiniz düğümü * bestFriend olarak atayacaksınız.

Her zaman printList() öğesini çağırmadan önce Jimmy'nin en iyi arkadaşının NULL olup olmadığını kontrol ederek bunu doğrulayabilirsiniz.

populateList (&bestFriend, numberOfFriends); 
İlgili konular