parcourant une liste chaînée en C ++
-
19-09-2019 - |
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.
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 égalfirstNode
? 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
estNULL
? - 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 deif
). Avec le changement ci-dessus, le noeud cible est garanti pour être stocké dansprevNode
(le cas échéant - voir le point suivant). - Pour des raisons de sécurité, il serait bon de vérifier que
prevNode
n'est pasNULL
. Cependant, comme Pavel mentionne, ce test est inutile sicurrentNode
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.