2017-03-15 6 views
0

J'ai implémenté l'algorithme de tri d'insertion en C#. La méthode renvoie un List<List<string>> qui enregistre toutes les étapes et les changements qui l'ont connu List, les variables qui ont été sélectionnées, etc.C#: Lors de l'ajout d'un élément à une liste, les éléments de liste précédents sont également remplacés par l'élément. Pourquoi?

Voici la méthode:

public List<List<int>> SortStepByStep(List<int> set) 
{ 
    List<List<int>> steps = new List<List<int>>(); 
    steps.Add(set); 

    for (int c1 = 1; c1 < set.Count; c1++) 
    { 
     Console.WriteLine(steps[0][0].ToString()); 

     int item = set[c1]; 

     set.Add(item); 
     steps.Add(set); 
     set.RemoveAt(set.Count - 1); 
     // ^^^^ This is just to visually display what number is being selected. 

     set.RemoveAt(c1); 

     steps.Add(set); 

     bool inserted = false; 
     for (int c2 = 0; c2 < c1; c2++) 
     { 
      if ((set[c2] > item || c2 == c1 - 1) && !inserted) 
      { 
       set.Insert((set[c2] <= item && (c2 == c1 - 1) ? c2 + 1 : c2), item); 
       steps.Add(set); 
       inserted = true; 
       break; 
       // Added the break in anyway because sometimes the inserted boolean failed to work. 
      } 
     } 
    } 
    return steps; 
} 

Qu'est-ce que la méthode renvoie en fait est juste la finale trié liste à chaque index de «étapes». Je l'ai suivi en écrivant les «étapes» à la console et peut le voir changer progressivement, mais je ne comprends pas pourquoi.

D'autres réponses mentionnent l'instanciation dans la boucle for, mais je ne pense pas que ce soit applicable ici.

Quel est le problème?

+1

Le problème est que vous ajoutez un seul et même objet de liste ** référence ** à vos 'steps' (il ne fait pas de copie pour vous). Remplacer ** all ** 'steps.Add (set);' avec 'steps.Add (set.ToList());' –

+1

Merci beaucoup, je n'ai pas compris que c'était comme ça que ça fonctionnait. Merci de m'avoir épargné beaucoup de temps! –

Répondre

1

Vos étapes liste contenant références à la même collection. À cause de cela, une fois que vous modifiez définir, chaque élément du étapes vous montrera la valeur mise à jour (ils pointent vers le même objet).

Essayez de changer steps.Add(set); en steps.Add(set.ToList()) ou steps.Add(new List<int>(set)), cela devrait créer une nouvelle liste au lieu de faire référence à l'ancienne.

+0

Merci beaucoup pour la réponse, j'ai besoin de lire dans les pages de théorie/msdn un peu plus attentivement! –