Question

Je me demandais s'il est possible de parcourir une liste liée à ceci:


currentNode = randomNode;//where randomNode may or may not = firstNode
prevNode = firstNode;
while(prevNode != currentNode && prevNode->link != currentNode)
{
    prevNode = prevNode->link;
}

Est-il possible de le faire en C ++ quand je suis en train de trouver le nœud avant currentNode dans une liste chaînée?

J'essaie de mettre en œuvre quelque chose comme ça dans une application de la console pour un travail scolaire Supposons donc que je ne peux pas utiliser quoi que ce soit de fantaisie comme les bibliothèques Boost / liste / tout ce qui rend la vie plus facile, etc. Donc, fondamentalement, je ne assez primitifs et les bibliothèques des types de données à ma disposition.

Était-ce utile?

La solution

Vous pouvez vous assurer que prevNode-> lien n'est pas une référence null soit, en cas currentNode ne fait lié.

Autres conseils

Cela devrait fonctionner très bien. Avez-vous essayé?

Ce code traverse une partie de votre liste, mais dont une partie dépend de quelle manière votre liste est liée. Si elle va de> queue BANDEAUX (lire: liens de nœud de tête à un noeud qui relie vers la queue) alors vous parcourir votre liste à partir de l'emplacement aléatoire à la queue. Si les liens sont la tête <-tail alors vous traverserez de l'emplacement aléatoire à la tête. Dans les deux cas, vous ne toucherait pas tous les noeuds dans la liste.

Toutes précède suppose une liste de liens en tant que tel:

[head]<->[0...N Nodes]<->[Tail]

Les liens peuvent être de toute façon.

En outre, vous pouvez relier les nœuds de la tête et la queue et de créer une liste chaînée circulairement. Dans ce scénario, il est possible de visiter tous les noeuds en parcourant simplement jusqu'à ce que vous êtes de retour à votre nœud d'origine.

Assurez-vous que vous considérez tous les cas limites possibles:

  • Qu'est-ce qui se passe randomNode est égal firstNode? Qu'est-ce que vous revenez? Qu'est-ce que devrait vous revenir?
  • Qu'est-ce qui se passe quand randomNode est le dernier nœud dans la liste?
  • Qu'est-ce qui se passe quand randomNode est NULL?
  • Qu'est-ce qui se passe quand randomNode est pas dans la liste?

Maintenant, tous ces cas peuvent être applicables, selon si vous savez quoi que ce soit au sujet randomNode, et certains d'entre eux peut être trivial. Mais ils sont tous peine d'y penser.

Si vous considérez tous ces très attentivement, il y a une solution simple et élégante qui les gère tous.

Le code a l'air bien, mais je suggère un changement mineur à votre état de while

while(prevNode != currentNode && prevNode != NULL)

Pour deux raisons

  • Votre code, sa version actuelle, pourrait arrêter si le nœud que nous recherchons est pointée par l'une ou prevNode prevNode->link (et donc nous aurons aucune idée que l'on particulière des deux points à currentNode - si nous voulions savoir, il faudrait vérifier avec une condition de if). Avec le changement ci-dessus, le noeud cible est garanti pour être stocké dans prevNode (le cas échéant - voir le point suivant).
  • Pour des raisons de sécurité, il serait bon de vérifier que prevNode n'est pas NULL. Cependant, comme Pavel mentionne, ce test est inutile si currentNode est garanti dans la liste.

Modifier en réponse à des commentaires

Étant donné que vous n'avez pas besoin de savoir si currentNode est prevNode ou prevNode->link, et que vous voulez arrêter (si possible) sur currentNode == prevNode->link, votre while d'origine est très bien. Cependant ...

  

il y a un si plus haut dans l'instruction   le code qui empêche   prevNode d'être null   déjà

Il semble que vous manquez le point de savoir pourquoi vous devriez vérifier NULL. Oui, ce qui est bon de vérifier avant, mais la raison pour laquelle nous avons le contrôle de NULL dans la boucle est dans le cas où currentNode est pas dans la liste, vous atteindrez le dernier nœud. On peut supposer que (si vous faites cela comme la plupart des autres listes chaînées) la valeur de link pour votre dernier nœud est NULL. Si oui, votre code actuel finira par finir par appeler NULL->link qui bien sûr va planter votre programme. Voilà pourquoi vous devriez toujours vérifier NULL

while(prevNode != NULL && prevNode != currentNode && prevNode->link!=currentNode)

Si vous êtes absolument sûr qui currentNode sera dans la liste, alors je guess que l'enregistrement est également inutile, mais il est vraiment une bonne habitude à prendre .

Vous pouvez même avoir:

while (prevNode && prevNode != currentNode)
    prevNode = prevNode->link;

Mais ce que vous avez l'air bien.

est que, lorsque le tout en une petite chose que je voudrais changer avec le code affiché comme (à part la possibilité discutée dans d'autres réponses de écoulage la fin de la liste si currentNode ne figure pas sur la liste ou tout autre traitement des erreurs) la boucle est fait, vous ne savez pas si les points de prevNode ou prevNode->link à currentNode. Ce n'est pas un énorme problème (puisque vous pouvez facilement tester), mais il me semble qu'il est préférable de tester cette situation de cas particulier avant la recherche, il est donc clair que c'est un cas particulier.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top