Doppelt verkettete Liste in C#



  • Hi ich versuche grade mit C++ Erfahrung C# zu lernen.
    Wie und wo finde ich ein Anwendungsbeispiel einer doppelt verketteten Liste mit Iteratoren?



  • Hi,

    das Konzept der Iteratoren gibt es als solches in C# nicht. Stattdessen wird ein sogenannter Enumerator verwendet. Eine doppelt verkettete Liste ist in der Klasse 'System.Collections.Generics.LinkedList<T>' zu finden. Die kann man einfach mit einer 'foreach'-Schleife durchlaufen (das geschieht dann eben über den Enumerator).



  • Danke erstmal dafür!

    Ich schilder mal mein Problem was ich habe.
    Ich habe eine Klasse Spieler:

    class Spieler
        {
            // --- Konstruktor ---
            public Spieler() { SpielerName = ""; SpielerID = 0; Token = false; InGame = false; }
    
            // --- Methoden ---
            public void aufnehmen(Stapel stapel) { }
            public void ausspielen(Stapel stapel) { }
            public void denken() { }
            public int getSpielerID() { return SpielerID; }
            public void setSpielerID(int ID) { SpielerID = ID; }
            public string getSpielerName() { return SpielerName; }
            public void setSpielerName(string Name) { SpielerName = Name; }
    
            // --- Variablen ---
            private string SpielerName;
            private int SpielerID;
            private bool Token;
            private bool InGame;
        }
    

    Jetzt möchte ich in einer anderen klasse Spieler in einer Liste Speichern:

    // --- Spieler erstellen ---
    
                try {
                    liste = new LinkedList<Spieler>();
                    for (int i = 0; i <= getAnzahlSpieler(); ++i) {
                        Spieler spieler = new Spieler();
                        Console.Write("Spieler Name{0}: ", i);
                        string Name;
                        Name = Console.ReadLine();
                        spieler.setSpielerName(Name);
                        spieler.setSpielerID(i);
                        liste.AddLast(spieler);
    
                    }
                }
                catch{
                    Console.Write("Fehler beim Erstellen der Spieler oder eingabe des Spieler Namens!");
                }
    

    Ich denke mal das ist soweit richtig.
    Wie komme ich jetzt jedoch wieder an die Spieler in der Liste ran, um z.b dessen Funktionen aufzurufen?



  • Wo ist denn das Problem beim Herankommen?

    Erst mal ein paar Bemerkungen zum Code: Der 'try'…'catch'-Block bringt nichts und ist absolut überflüssig.

    Dann: C# ist nicht Java oder C++. Getter und Setter implementiert man anders, dafür gibt es Properties. Wobei hier die Frage ist, ob die Setter überhaupt Sinn ergeben. Wie oft ändert ein Spieler schon seinen Namen? Doch wohl eher nie, oder?

    Sinnvoller wäre ein korrekter Einsatz des Konstruktors.

    Und zu guter Letzt: Ist hier eine verkette Liste wirklich angebracht? Eigentlich kann man einfach immer die 'List' verwenden (ironischerweise eine Vektor-Implementierung), das passt fast immer.

    class Gamer {
        private readonly string m_Name;
        private readonly int m_Id;
        private bool m_Token = false;
        private bool m_InGame = false;
    
        public Gamer(string name, int id) {
            m_Name = name;
            m_Id = id;
        }
    
        public string Name { get { return m_Name; } }
    
        public int Id { get { return m_Id; } }
    
        public void TakeUp(Stack stack) { /* … */ }
    
        public void PutDown(Stack stack) { /* … */ }
    }
    
    var gamers = new List<Gamer>(NumberOfGamers);
    
    for (int i = 0; i < NumberOfGamers; ++i) {
        Console.WriteLine("Spieler Name {0}: ", i);
        var name = Console.ReadLine();
        gamers.Add(new Gamer(name, i));
    }
    

    Und das Durchgehen der Spieler:

    foreach (var gamer in gamers)
        Console.WriteLine(gamer.Name);
    

    /EDIT: Mein Code ist in C# 3 geschrieben. Wenn Du noch eine ältere Version verwendest (= älter als Visual Studio 2008), dann funktioniert die Deklaration mittels 'var' so nicht, es reicht aber, an dieser Stelle einfach immer den konkreten Variablentyp einzufügen, genauso wie in C++.



  • Über den Index oder eben der for each schleife. In der Dokuemntation zur Liste findest Du ein Beispiel.



  • Wie kann ich den Inhalt einer liste mischen?



  • Einfach mal intuitiv:
    Du könntest mit einem Zufallsgenerator zwei Knoten auswählen und diese mit RemoveAt() und Insert() tauschen. Das vllt doppelt so oft, wie es Elemente in der Liste gibt.



  • Mitbewohner schrieb:

    Wie kann ich den Inhalt einer liste mischen?

    http://www.activevb.de/cgi-bin/tippupload/preview.pl?tippnr=158

    Das ist eine Implementierung von Knuths Mischalgorithmus, der auch in C++ in 'std::random_shuffle' zum Einsatz kommt.



  • Danke! 🙂

    Nächste frage:
    Wie kann ich teile des Inhalts einer Liste in eine andere moven.

    Sprich ich will 4 von 7 Elementen in eine Neue liste kopieren und die kopierten Elemente in der Alten liste löschen.



  • Mitbewohner schrieb:

    Wie kann ich teile des Inhalts einer Liste in eine andere moven.

    Sprich ich will 4 von 7 Elementen in eine Neue liste kopieren und die kopierten Elemente in der Alten liste löschen.

    Wenn Du C# 3.0 benutzt:

    var begin = 5;
    var count = 3;
    var newList = oldList.Skip(begin).Take(count).ToList();
    oldList.RemoveRange(begin, count);
    

    Ansonsten musst Du wohl oder übel erst die neue Liste erstellen und dann die Elemente einzeln hinzufügen. 'RemoveRange' kannst Du trotzdem benutzen.



  • Hallo,
    folgendes...

    Ich habe eine Liste in der ich ein Element in der Mitte lösche.
    Wie kann ich diesen Leerraum in der Mitte füllen? Ich dachte mir indem ich ab der Lücke jedes Element um eins nach Links verrücke? Ich weis aber nicht wie es geht... Oder gibt es noch eine bessere Lösung?



  • Die 'Remove*'-Funktionen füllen die Lücke von selbst, Du musst nichts weiter tun. Wenn solche Operationen (Löschen aus der Mitte) häufiger vorkommen, ist die LinkedList aber evtl. doch effizienter.


Anmelden zum Antworten