2009-08-22 7 views
0

Vous essayez de comprendre pourquoi mes pointeurs de classe list() sont remplacés par le troisième nœud. Ce qui se passe dans la fonction d'insertion (ci-dessous) est que la troisième fois que la fonction d'insertion est appelée, mon pointeur de nœud headByName->nextByName est écrasé par le troisième nœud, alors qu'il devrait pointer vers le second. Donc, comme vous pouvez le deviner, le 4ème nœud est écrasé par le 5ème et le 6ème nœud est écrasé par le 7ème, d'où le "saut" dans les nœuds.LinkedList "node jump"

Les attributs de l'objet cave sont passés à travers la cave cteur puis à la fonction list::insert par ces appels dans les principaux:

//main.cpp 
//the attributes of the winery object are the paramaters, name, location, acres, rating: 
list *listPtr = new list(); 
wineries->insert(winery("Lopez Island Vinyard", "San Juan Islands", 7, 95)); 
wineries->insert(winery("Gallo", "Napa Valley", 200, 25)); 
wineries->insert(winery("Cooper Mountain", "Willamette Valley", 100, 47)); 

Ensuite, la cave cteur est appelée où j'affecter le memembers pointeur privé:

//winery.cpp 
winery::winery(const char * const name, const char * const location, const int acres, const int rating) 
    : m_acres(acres), m_rating(rating) 
{ 
    if (name) 
    { 
     size_t len = strlen(name) +1; 
     m_name = new char[len]; 
     strcpy_s(m_name, len, name); 
    } 
    else 
     m_name = NULL; 

    if (location) 
    { 
     size_t len = strlen(location) +1; 
     m_location = new char[len]; 
     strcpy_s(m_location, len, location); 
    } 
    else 
     m_location = NULL; 
} 

Et puis au problème en cours: Si vous pouvez imaginer que cette fonction a déjà été appelée deux fois, current_node aura le thrid win. headByName aura le premier noeud et dans celui-ci [+], headByName->next aura le troisième. J'ai besoin de headByName->next pour avoir le second. Je me demande juste pourquoi il a été écrasé ..

// list.cpp 
void list::insert(const winery& winery) 
{ 
    node *current_node = new node(winery); // the third wineries info! 
    node *next_node  = NULL; 
    list *list_ptr  = NULL; 
    do 
    { 
     if (headByName == NULL || headByRating == NULL) // then we are here for the first item 
     { 
      headByName = current_node; // the list ptrs have a node address. 
      headByRating = current_node; 
     } 
     else 
     {   

      next_node     = current_node; 
// transfer by the next call in main. 
      headByName->nextByName  = next_node; 
      headByRating->nextByRating = next_node; 

     } 
    } while (headByName == NULL || headByRating == NULL); 

    next_node = NULL; 
    current_node = NULL; 
} 

Quelqu'un pourrait trouver mon deuxième noeud? oh ouais, et les pointeurs qui sont disponibles pour moi:

struct node 
{ 
    winery item; 
    node * nextByName; 
    node * nextByRating; 
}; 

class list 
{ 
    ... 
private: 
    node * headByName; 
    node * headByRating; 
}; 

cela pourrait être d'une certaine importance, son corps du nœud cteur:

//list.cpp 
list::node::node(const winery &winery) : 
nextByName(NULL), nextByRating(NULL), item(winery.getName(), 
winery.getLocation(), winery.getAcres(), winery.getRating()) 
{ 
    // where the item paramters are all pub-mem functions of the winery class. 

} 

Répondre

2

Je pense que problème ici est:

headByName->nextByName  = next_node; 
headByRating->nextByRating = next_node; 

Vous remplacez toujours le deuxième noeud. Comme je comprends, vous devriez trouver le dernier en parcourant toute la liste et insérer après le dernier nœud.

1

Eh bien, le principal problème est que lorsque vous insérez un nœud que vous définissez toujours

headByName->nextByName  = next_node; 
headByRating->nextByRating = next_node; 

Ainsi, le second nœud est rempli correctement. Alors le troisième vient et écrase le deuxième noeud et le deuxième noeud disparaît dans l'oubli.

0

Votre constructeur n'est pas lié, mais la première chose qui colle est cette erreur dans la logique d'attribution:

headByName->nextByName  = next_node; 
headByRating->nextByRating = next_node; 

Ici vous configurez toujours le nœud suivant du nœud de tête (2ème noeud) à tout le nouveau noeud est. C'est pourquoi le deuxième noeud de la liste est toujours le plus récent.

Si vous souhaitez ajouter des éléments à la fin de la liste, vous devez conserver un pointeur de queue qui pointe vers le dernier élément inséré, en commençant par l'élément de tête.

Avec que votre mission serait plutôt:

tail_pointer->nextByName = current_node; 
tail_pointer->nextByRating = current_node; 

tail_pointer = current_node; 

En second lieu, la boucle do/while est inutile.headByName et headByRating sera toujours mis à pointer vers le nouveau nœud alloué current_node, ce qui signifie que

while (headByName == NULL || headByRating) 

sera toujours sortir de la boucle (à condition que vous n'êtes pas manquer de mémoire bien sûr).

Vous attribuez toujours les deux variables en utilisant l'initialisation paresseuse dans le premier bloc if dans list :: insert.

Les insertions de liste liée sont des temps constants, O (1), car vous n'avez pas besoin d'itérer quoi que ce soit dans une boucle - vous savez toujours exactement où opérer: tail_pointer.

En outre, ceci:

next_node = NULL; 
current_node = NULL; 

est un bon style à mon avis, mais ne Désallocation pas oublier que vous n'êtes pas réellement les données avec cela, dans le cas où était votre intention :-)

Gardez un pointeur de queue qui pointe toujours vers l'article le plus récent!

Questions connexes