10
votes

Supprimer de la liste liée C #

J'essaie de supprimer un nœud, si x correspond actuellement à un INT dans ma liste liée.

J'ai essayé cela, mais une fois qu'il élimine le nœud, il jette une erreur lors de l'examen de la boucle p>

public void DeleteNode(int x, LinkedList<name> myLinkedList) {
    foreach (name item in myLinkedList) {
         if (item.num.equals(x)) mylinkedList.Remove(x);
    }
}

c#

1 commentaires

Impossible d'utiliser un foreach , besoin de passer à un pour .


6 Réponses :


0
votes

Si vous appelez Supprimer lors d'un foreach , il invalidera l'énumérateur, il n'est donc pas autorisé.

Changer votre foreach à un simple pour boucle.


0 commentaires

0
votes

Dans cette situation, je crée généralement une collection temporaire et l'ajoutez-la si elle doit être supprimée. Ensuite, je boucle à travers cette liste en retirant de l'original.


0 commentaires

30
votes

Oui, vous ne pouvez pas itérer une collection et la modifier en même temps. Toutefois, linkedlist vous permet de faire l'itération explicitement assez facilement: xxx

Notez que vous ne pouvez pas vous éloigner avec juste prenant nœud = nœud = nœud .Next; comme dernière ligne; Le nœud est invalidé lorsqu'il est supprimé.

Cette approche permet une seule traversée de la liste dans O (n) et sera probablement l'approche la plus efficace que vous trouverez. Il n'exige pas de copier ou de collection avec une collection (disons Liste ) avec une complexité d'élimination moins efficace.


13 commentaires

Cela présente également l'avantage d'être O (n) au lieu de O (n ^ 2) en considérant la complexité temporelle de Supprimer (t) versus Supprimer (linkedlistnode ) .


@Ronwarholic: absolument. J'avais supposé que c'était implicite, mais je vais éditer pour l'énoncer :)


Merci Jon, je reçois toujours une erreur sur la première partie, je ne peux pas convertir un .LinkedListNode à .LinkedList. Ma liste liée est une collection d'articles, pas seulement 1 INT (bien que l'int est la pièce que je comparais)


@timmy: Quelle "première partie"? Veuillez identifier la ligne de mon code que vous voulez dire, et l'erreur exacte . Je modifierai mon message pour inclure la déclaration de méthode.


@timmy: Et le message d'erreur exact? Cela devrait être absolument bien. myLinkedList est un linkedlist , et j'utilise simplement la propriété .


@Jonskeet var nœud = myLinkedlist.First; Je reçois une erreur sur MyLinkedList.First à dire ne peut pas convertir implicitement le type System.Collections.Generic sur LinkedListnode à System.Collections.Generic.LinkedList


@timmy: Cela ne devrait pas arriver si vous utilisez vraiment var - Avez-vous essayé de donner nœud un type explicite? Le code exactement comme j'ai écrit bien compiler. Quelle version de C # utilisez-vous? Si vous ne pouvez toujours pas le faire fonctionner, postez un programme court mais complet qui démontre le problème - car comme je le dis, le code que j'ai affiché est bien compilé.


@Jonskeet Désolé Jon, votre code a raison. J'ai essayé d'utiliser mon type au lieu de var. Merci!


@Jonskeet, je suis tombé sur ce post cherchant google et j'essaie de comprendre: pourquoi pas seulement utiliser foo.remove (foo.first (x => x.foo == bar))? Il semble que d'abord () soit mis en œuvre pour itérer la liste de toute façon, et devrait donc entraîner l'exécution du même code, mais ne nécessite pas d'écrire cette méthode que vous avez fournie dans ce poste?


@dferraro: Non, car un linkedlist ne met pas en œuvre iEnumerable > - il implémente simplement ienumerable . De plus, ma méthode supprime toutes les entrées correspondant à la valeur donnée.


@Jadoon: LinkedList ne prétend pas être thread-coffre-fort pour commencer.


@ Jonskeet Comment devrais-je y aller à ce sujet, en utilisant un verrouillage minimum. De plus, je souhaite supprimer, plusieurs articles à la fois


@Jadoon: Vous devriez rechercher une collection de fil-sécurité ou effectuer un verrouillage approprié, fondamentalement ...



0
votes

La façon dont j'écris cela, sans invalider l'itérateur, est la suivante: xxx


5 commentaires

C'est ce que Shlemiel le peintre ferait.


@Jon, pour être juste, je doute que cela compte vraiment .. Bien sûr, je ne l'utilise que pour les tableaux, mais le code est suffisamment solide pour tout type d'itérateur.


@Blindy: Pensez-vous qu'il est particulièrement peu probable d'avoir une liste liée, disons, 10 000 éléments? Ce n'est pas une énorme collection - mais la différence entre O (n) et O (n ^ 2) est assez grande à ce point ...


@Jon, cette chose (principalement) se développe pire par rapport au nombre d'articles que vous êtes Suppression , donc si nous parlons d'une liste que vous supprimez des dizaines de milliers d'articles assez souvent que vous remarquez souvent que vous remarquiez que vous remarquiez. La différence, alors oui, c'est un peu peu probable.


@Blindy: Cela ne prend que quelques centaines d'articles d'une liste de 10 000 articles pour provoquer un mal de tête avec cette approche, imo. BTW, j'ai vraiment été mordu par quelque chose comme ça dans le monde réel - ironiquement, un peu de code qui était censé être optimiser supprimer une collection d'un ensemble. J'ai perdu toute une matinée en train d'essayer de travailler où mon code était faux. Pas assez la même situation, mais le même genre de différence caractéristique de performance. I blogué à ce sujet ...



0
votes

i Supprimer des éléments de la liste de la manière suivante:

for (int j = lst.Count - 1; j >= 0; j--)
   {
    var elem= lst[j];
    lst.Remove(elem);
    }


0 commentaires

0
votes

info est une classe.

Ceci trouvera via LinkedList et Supprimer le premier élément Qui est NO La valeur de la propriété est 1 xxx


0 commentaires