Frage

Hallo Ich versuche, einige der Praxis mit verketteten Listen zu erhalten.

I definiert eine Objektklasse namens Student:

public class Student
{
      protected string  Student_Name;
      protected int Student_ID;
      protected int Student_Mark;
      protected char    Student_Grade;

      public Student()  // default Constructor
      {
         Student_Name = "           ";
         Student_ID = 0;
         Student_Mark = 0;
         Student_Grade = ' ';
        }

      public Student(string Sname, int Sid, int Smark, char Sgrade) // Constructor
      {
         int len = sname.Length;
         Student_Name = sname.Substring(0, len);
         //Student_Name = sname.Substring(0, sname.Length);
         Student_ID = Sid;
         Student_Mark = Smark;
         Student_Grade = Sgrade;
      }
}

und dann eine Node Klasse:

public class S_Node
{
      public Student    Element;
      public S_Node Link;

      public S_Node()
      {
         Element = new Student();
         Link = null;
      }

      public Node(Student theElement)
      {
         Element = theElement;
         Link = null;
      }
}

und die LinkedList:

public class S_LinkedList
{
    protected S_Node header;
    protected S_Node tail;

    public S_LinkedList()
    {
       header = new S_Node();
       Tail = new S_Node();
       header.Link = Tail;
    }

    // METHODS which i don't know how to do it (never use linkedlist before)
}

Ich brauche diese Daten zu organisieren einen „LinkedList Datenstrukturtyp“ verwendet wird.

enthalten alle Methoden des LinkedList als Knoten zur Liste hinzufügen, wie ich gelernt habe -> (Insert), Löschen von Knoten aus der Liste, wie ich gelernt habe -> ((Entfernen), die Listen Verfahrgeschwindigkeit I‘ habe gelernt -> ((druckt), Suche nach einem Knoten in der Liste, wie ich gelernt habe -> ((suchen, FindPrevious), um das Problem, das ich bin selbstlernend und ich habe versucht, das Netz zu suchen und mehr von der Lese dumm C #, das war eine Katastrophe. Ich habe zu viel zu tun, dass ich so traurig bin, dass ich weiß nicht, wie es zu vervollständigen.

Ich versuche hart diese Klassen zu verwenden, um ein ausführbares Programm zu schreiben und zu testen.

Wenn Sie beim Ausfüllen dieses Programm (nicht hoffen) helfen wollen nicht zumindest zeigen mir einige konkrete Beispiele oder Ideen, schließlich bin ich ein selflearner Aussenseiter: -)

War es hilfreich?

Lösung

 the head of the list.
 ( item1
   Element: student1
   Next ------------> ( item2
  )                     Element: student2
                        Next ------------> ( item3
                      )                      Element: student3
                                             Next: null
                                           )
                                           the tail of the list.

Zunächst einmal für Sie die StudentList Klasse in der Lage sein zu schreiben, müssen Sie zuerst den Client-Code schreiben. Client-Code ist der Code, der Studentenliste verwendet. Auch nicht nur eine Sache auf einmal schreiben und wirft es weg. Stattdessen schreibt eine ganze Reihe von [Test] Fällen, die die verschiedenen Möglichkeiten üben Sie Notwendigkeit mit dem StudentList zu interagieren. Schreiben auch Ausnahmefälle. Aber nicht ein Schweizer Taschenmesser einer Klasse zu schreiben versucht sein, die alles tut, nur weil es kann. Schreiben Sie die minimale Menge an Code, der die Arbeit erledigt wird.

Wie Sie die Klasse verwenden müssen, wird stark diktieren, wie die Klasse aufgebaut ist. Dies ist die Essenz von TDD oder Test-Driven Design.

Ihre größte Problem, das ich sehe, ist, dass Sie keine Ahnung haben, wie Sie die Klasse verwenden möchten. So tun lässt, dass zuerst.

// create a list of students and print them back out.
StudentList list = new StudentList();
list.Add( new Student("Bob", 1234, 2, 'A') );
list.Add( new Student("Mary", 2345, 4, 'C') );

foreach( Student student in list)
{
    Console.WriteLine(student.Name);
}

Ich füge die Schüler auf die Liste, und dann drucke ich aus.

Ich habe keine Notwendigkeit für meinen Client-Code innerhalb des StudentList zu sehen. StudentList versteckt Deshalb, wie es die verknüpfte Liste implementiert. Lassen Sie uns die Grundlagen des StudentList schreiben.

public class StudentList 
{
    private ListNode _firstElement; // always need to keep track of the head.

    private class ListNode
    {
        public Student Element { get; set; }
        public ListNode Next { get; set; }
    }

    public void Add(Student student) { /* TODO */ }

}

StudentList ist ziemlich einfach. Intern verfolgt es den ersten oder Kopfknoten. Die Verfolgung des ersten Knotens ist offensichtlich immer erforderlich.

Sie können auch fragen, warum ListNode innerhalb von StudentList deklariert wird. Was passiert, ist die ListNode Klasse der StudentList Klasse nur zugänglich ist. Dies geschieht, weil StudentList nicht die Details geben, will es interne Implementierung ist, weil sie alle Zugriff auf die Liste steuert. StudentList nie offenbart, wie die Liste implementiert ist. Die Umsetzung Versteck ist ein wichtiges OO-Konzept.

Wenn wir Client-Code erlauben direkt die Liste zu bearbeiten, es wäre kein Punkt StudentList ist der erste Ort.

Lassen Sie uns gehen Sie vor und implementieren die Add () Betrieb.

public void Add(Student student)
{
    if (student == null)
        throw new ArgumentNullException("student");

    // create the new element
    ListNode insert = new ListNode() { Element = student };

    if( _firstElement == null )
    {
        _firstElement = insert;
        return;
    }

    ListNode current = _firstElement;
    while (current.Next != null)
    {
        current = current.Next;
    }

    current.Next = insert;
}

Die Add Operation hat das letzte Element in der Liste zu finden und stellt dann die neue ListNode am Ende. obwohl nicht sehr effizient. Es ist zur Zeit O (N) und Hinzufügen langsamer erhalten, wie die Liste länger wird.

Hier können Sie diese ein wenig für Einsätze optimieren und die Add-Methode neu schreiben. Um hinzufügen schneller alles, was wir tun müssen, ist hat StudentList Spur des letzten Elements in der Liste zu halten.

private ListNode _lastElement;  // keep track of the last element: Adding is O(1) instead of O(n)

public void Add(Student student)
{
    if( student == null )
        throw new ArgumentNullException("student");

    // create the new element
    ListNode insert = new ListNode() { Element = student };

    if (_firstElement == null)
    {
        _firstElement = insert;
        _lastElement = insert;
        return;
    }

    // fix up Next reference
    ListNode last = _lastElement;
    last.Next = insert;
    _lastElement = insert;
}

Nun, wenn wir hinzufügen, wir iterieren nicht. Wir müssen nur den Überblick über die Kopf und Schwanz Referenzen zu halten.

Als nächstes: der foreach-Schleife. StudentList ist eine Sammlung, und ist eine Sammlung wir darüber aufzählen wollen und C # 's foreach verwenden. Der C # Compiler kann nicht auf magische Weise laufen. Um die foreach-Schleife verwenden Wir müssen die Compiler mit einem Enumerator bereitzustellen, selbst zu verwenden, wenn der Code schreiben wir nicht explizit den Enumerator verwenden erscheinen.

Zunächst aber lässt wieder besuchen, wie wir über eine verknüpfte Liste durchlaufen.

// don't add this to StudentList
void IterateOverList( ListNode current )
{
    while (current != null)
    {
        current = current.Next;
    }
}

Okay. so lassen Sie uns in C # 's foreach Schleife Haken und einen Enumerator zurück. Dazu müssen wir StudentList ändern IEnumerable zu implementieren. Dies ist immer ein wenig fortgeschritten, aber Sie sollten herausfinden können, was los ist.

// StudentList now implements IEnumerable<Student>
public class StudentList : IEnumerable<Student>
{
    // previous code omitted

    #region IEnumerable<Student> Members
    public IEnumerator<Student> GetEnumerator()
    {
        ListNode current = _firstElement;

        while (current != null)
        {
            yield return current.Element;
            current = current.Next;
        }
    }
    #endregion

    #region IEnumerable Members
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
    #endregion
}

Es sollte möglich sein, die verknüpfte Liste Iteration dort zu entdecken. Lassen Sie sich nicht durch das yield Stichwort geworfen. Alle Ausbeute macht, ist die aktuelle Student zurück in die foreach-Schleife zurück. Der enumarator stoppt Studenten zurückkehrte, wenn es bis zum Ende der verketteten Liste wird.

Und das ist es! Der Code funktioniert so, wie wir es wollen.


* Dies ist keineswegs die einzige Art und Weise bedeutet, die Liste zu implementieren. Ich habe entschieden, die Liste Logik in dem StudentList zu setzen und halten ListNode sehr einfach. Aber der Code tut nur das, was meine erste Einheit Testanforderungen und nichts mehr. Es gibt mehr Optimierungen Sie könnten machen, und es gibt andere Wege, um die Liste zu konstruieren.

Für die Zukunft: Was Sie tun müssen, ist erstellen Sie zuerst [Einheit] Tests für das, was Ihr Code tun muss, fügen Sie dann die Implementierung vonerforderlich ist.


* FYI schrieb ich auch die Student-Klasse. Bad Namensgebung und seltsame Gehäuse aus einem C # persepctive, den Code nicht erwähnen Sie zur Verfügung gestellt nicht kompilieren. Ich ziehe den _ als Führer zu privaten Membervariablen. Manche Menschen wissen nicht, dass mögen, aber Sie diese neu sind, so werde ich sie verlassen in, weil sie leicht zu erkennen.

public class Student
{
    private string _name;
    private int _id;
    private int _mark;
    private char _letterGrade;

    private Student()  // hide default Constructor
    { }

    public Student(string name, int id, int mark, char letterGrade) // Constructor
    {
        if( string.IsNullOrEmpty(name) )
            throw new ArgumentNullException("name");
        if( id <= 0 )
            throw new ArgumentOutOfRangeException("id");

        _name = name;
        _id = id;
        _mark = mark;
        _letterGrade = letterGrade;
    }
    // read-only properties - compressed to 1 line for SO answer.
    public string Name { get { return _name; } }
    public int Id { get { return _id; } }
    public int Mark { get { return _mark; } }
    public char LetterGrade { get { return _letterGrade; } }
}
  • Prüfparameter
  • achten Sie auf die verschiedenen Gehäuse von Eigenschaften, Klassen und Variablen.
  • den Standardkonstruktor verstecken. Warum will ich Studenten schaffen, ohne reale Daten?
  • bieten einige schreibgeschützte Eigenschaften.
    • Diese Klasse ist unveränderlich wie geschrieben (das heißt, wenn Sie einen Schüler zu erstellen, können Sie es nicht ändern).

Andere Tipps

Ich werde ein für Sie tun! Sie müssen Diagramme mit jedem Knoten als Box ziehen und herauszufinden, was Code, den Sie verwenden müssen, um für jeden Betrieb der Liste zu ändern. Sehen Sie diese für einige Inspiration:

http://en.wikipedia.org/wiki/Linked_list

Die Diagramme dort zeigen nicht die Hauptliste Klasse als Box, die Sie haben sollten, mit zwei Pfeilen für den Kopf und Schwanz kommen aus ihm heraus.

Zeichnen Sie sich einige Diagramme für die beiden Fälle in der Insert-Methode, herauszufinden, was los ist. Ein Diagramm für wenn es nichts in der Liste und Header ist null, und ein weiteres Diagramm, denn wenn es etwas bereits in der Liste. Dann von dort die anderen Operationen trainieren.

public class S_LinkedList {

    protected S_Node header = null;

    protected S_Node tail = null;

    public S_LinkedList()
    {
    }

    // METHODS which i don't know how to do it (never use linkedlist before)
    void Insert(Student s)
    {
        if( header == null )
        {
            header = new S_Node(s);
            tail = header;
        }
        else
        {
            tail.Link = new S_Node(s);
            tail = tail.Link;
        }
    }
}

Die Operationen, die Sie fehlen, sind:

hinzufügen:

setzen Sie den Link des Endknoten den zusätzlichen Knoten zu sein und den Schwanz setzt der neue Knoten sein.

Entfernen / Löschen:

ist ein bisschen schwierig, wenn Sie nicht über eine doppelt verknüpfte Liste, aber mit einer einfach verketteten Liste gehen throught ihn Liste aus dem Kopf, bis Sie den Knoten finden Sie benötigen den vorherigen Knoten in einer separaten Variable zu halten. Wenn Sie die Knoten finden Sie entfernen den Link des vorherigen Knoten auf, dass Link-Knoten. Eine Optimierung könnte sein, zu prüfen, ob es nicht die Verbindung für Sie suchen. macht es alternativ eine doppelt verknüpfte Liste und Sie müssen nicht aus dem vorherigen Knoten zu halten.

finden:

Fahren Sie die Liste von Knoten, bis Sie zum Knoten die, die Sie suchen, nicht finden.

lesen Sie Wikipedia-Artikel für weitere Informationen.

Lesen Sie dieser ...

Obwohl, wenn Sie wirklich wissen wollen, wie dies zu tun, sollten Sie es in C oder C ++ schreiben zumindest dann würden Sie etwas Nützliches tun ...

Eigentlich sehe ich keinen Grund, Ihre eigene verknüpfte Liste in C # zu schreiben (andere dann zu lernen, wie es funktioniert), da bereits die .NET LinkedList generische Klasse enthält.

Das Konzept der verkettete Listen ist nicht sehr schwer zu verstehen. Die Umsetzung auf der anderen Seite ... kann ein bisschen schwierig bekommen.

Ich kann auch versuchen, Informationen im Internet über sie verstehen Ihre Frustration zu finden. Ich habe vor in Ihrem Boot gewesen und alles variiert von Ort zu Ort. Sie wollen wirklich möglicherweise in einem Datenstruktur Buch investieren, wie Sie Ich denke, die Informationen, die Sie werden viel mehr klar und hilfreich, als die meisten Informationen, die Sie in der freien Natur finden finden.

eine verknüpfte Liste Implementierung in Java / C # wird viel einfacher, wenn Sie noch nie ll die verwendet haben. Allerdings, wenn Sie ein besseres Gefühl dafür bekommen Sie ein viel besseres Verständnis für den ll ist erhalten, indem sie in C / C ++ Erstellen.

Von den Code oben, du bist besser dran denken jedes S_Node sein als nur regelmäßige Knoten, anstatt zu denken, der es als Student Knoten ein Studenten Objekt enthält (Hoffnung, die Sinn macht). Gleichen Regeln gelten für Ihre S_LinkedList Klasse. Eine verkettete Liste ist eine Liste Modus aus Knoten. Diese Knoten enthalten Studenten Objekte.

Hope, das hilft.

Versuchen Sie dies als Student-Klasse.

public class Student
{
    protected string Name;
    protected int ID;
    protected int Mark;
    protected char Grade;

    public Student()  // default Constructor
    {
        Name = "";
        ID = 0;
        Mark = 0;
        Grade = '';
    }

    public Student(string Name, int ID, int Mark, char Grade) // Constructor
    {
        this.Name = Name;
        this.ID = ID;
        this.Mark = Mark;
        this.Grade = Grade;
    }
}

Ihre Frage, wie ich es gelesen habe, ist zu vage. Ich würde beginnen mit ‚verkettete Listen‘ googeln oder ein Buch über ‚Datenstrukturen‘ aufnehmen. Wenn Sie in ein bestimmtes Problem laufen, fragen Sie es hier auf, und ich bin sicher, dass jemand wird Ihnen helfen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top