using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Text; namespace _07KeyValueList { class KeyValueListe /*: IComparable>*/ where K : IComparable { // Die Klasse Element ist nun eine *private* Klasse der Klasse StringListe // Die Methoden von StringListe dürfen auf private Member zugreifen // Methoden außerhalb von StringListe dürfen dies nicht! private class Element // Element ist eine private Hilfsklasse der Klasse StringListe { public K key; public V val; public Element next = null; public Element(K key, V val) { this.key = key; this.val = val ; } public override string ToString() => $"{key}: {val}"; } Element anf = null, ende = null; int anz = 0; // Sehr sinnvoll für Index-Ops //public StringListe() { } private void AddEnd(K key, V val) { Element neuesElement = new Element(key,val); // 1. Neues Element anlegen anz++; if (anf == null) // 2. Leere Liste? anf = ende = neuesElement; else { ende.next = neuesElement; // 3. Neues Element am Ende anfügen ende = ende.next; } } #region Weitere Methoden //public void AddFront(T daten) //{ // // 1. Leere Liste // // 2. Es existiert mind. ein Element // Element neuesElement = new Element(daten); // Neues Element anlegen // anz++; // if (anf == null) // 1.Fall: Leere Liste? // anf = ende = neuesElement; // else // { // neuesElement.next = anf; // 2. Fall // anf = neuesElement; // } //} ////public void AddBeforeNth(int index, string name) ////{ //// if (index < 0 || index > anz) //// throw new ArgumentOutOfRangeException("Index außerhalb der Listengröße"); //// if (index == 0) //// AddFront(name); //// else if (index == anz) //// AddEnd(name); //// else //// { //// Element neu = new Element(name); //// anz++; //// Element item = anf; //// for (int i = 1; i < index; i++) //// item = item.next; //// neu.next = item.next; // Die Reihenfolge dieses und des nächsten Befehls ist ENTSCHEIDEND! //// item.next = neu; //// } ////} //public void AddSorted(T daten) //{ // // 1. Fall: Leere Liste oder Anfügen am Listenende // if (anf == null || ende.key.CompareTo(daten) <= 0) // AddEnd(daten); // else // { // if (daten.CompareTo(anf.key) <= 0) // AddFront(daten); // else // { // // Wir wissen: Das neue Element ist nicht das erste und nicht das letzte Element // Element neu = new Element(daten); // anz++; // Element item = anf; // while (item.next.key.CompareTo(daten) < 0) // item = item.next; // neu.next = item.next; // item.next = neu; // } // } //} //public bool Suche(T daten) //{ // for (Element item = anf; item != null; item = item.next) // { // if (item.key.CompareTo(daten) == 0) // return true; // } // return false; //} //public void DeleteFirst() //{ // // 1.Fall: Liste ist leer // // 2.Fall: Liste besteht nur aus einem Element // // 3.Fall: Liste hat mehr als ein Element // if (anf == null) // 1. Fall // return; // anz--; // if (anf == ende) // 2. Fall // anf = ende = null; // else // anf = anf.next; // 3. Fall //} //public void DeleteLast() //{ // // 1.Fall: Liste ist leer // // 2.Fall: Liste besteht nur aus einem Element // // 3.Fall: Liste hat mehr als ein Element // if (anf == null) // 1. Fall // throw new NullReferenceException("Die Liste ist leer"); // anz--; // if (anf == ende) // 2. Fall // anf = ende = null; // else // 3. Fall // { // Wir wissen: Die Liste hat mehr als ein Element, d.h. es gibt ein // // vorletztes Element vorletzter.next == ende // Element vorletzter = anf; // while (vorletzter.next != ende) // vorletzter = vorletzter.next; // vorletzter.next = null; // ende = vorletzter; // } //} //public void DeleteNth(int index) //{ // // 1.Fall: Liste ist leer ODER Ind>=anz --> Fehler // // 2.Fall: Ind == 0 --> DeleteFirst // // 3.Fall: Ind == anz-1 --> DeleteLast // // 4. Bis hierher: Liste hat mind. ein Element und das zu löschende Element // // ist nicht das Erste oder Letzte // if (anz == 0 || index >= anz) // 1. Fall // throw new ArgumentOutOfRangeException("Außerhalb der Anzahl der Listenelemente"); // if (index == 0) // 2. Fall // DeleteFirst(); // else if (index == anz - 1) // 3. Fall // DeleteLast(); // else // { // Element vorletzter = anf; // for (int i = 0; i < index - 1; i++) // Liste bis zum n-1-ten Element durchlaufen // vorletzter = vorletzter.next; // vorletzter.next = vorletzter.next.next; // anz--; // } //} //public void DeleteByName(T other) //{ // // leere Liste ohne Elemente // if (anf == null) // return; // // erstes Element = gesuchtes Element // if (anf.key.CompareTo(other) == 0) // DeleteFirst(); // // Wir wissen jetzt: // // Liste hat mind. ein Element UND das erste Element ist nicht das gesuchte Element // else // { // Element item = anf; // // Durchlaufen der Liste // // solange Elemente in Liste vorhanden und gesuchtes Element noch nicht gefunden // while (item.next != null && item.next.key.CompareTo(other) != 0) // item = item.next; // // Wenn gesuchtes Element in Liste vorhanden // // item = "B" // if (item.next != null) // "C" // { // anz--; // // Nächstes Element überspringen = löschen // item.next = item.next.next; // item.next = null // // Wenn gesuchtes Element == letztes Element: // if (item.next == null) // ende = item; // } // } //} #endregion public void Print() { for (Element item = anf; item != null; item = item.next) { Console.WriteLine(item); } } public IEnumerator> GetEnumerator() { for (Element item = anf; item != null; item = item.next) { yield return new KeyValuePaar(item.key, item.val); } } //public IEnumerable Filter(string pattern) //{ // for (Element item = anf; item != null; item = item.next) // { // if (item.daten.Contains(pattern)) // yield return item.daten; // Merken dieser Ausführungsposition // // UND Zurückliefern von item.name // // Beim nächsten Aufruf von GetEnumerator() wird // // an der gespeicherten Pos. weitergemacht. // } //} private Element ElementSearch(K key) { for (Element item = anf; item != null; item=item.next) { if (item.key.CompareTo(key) == 0) return item; } return null; } public V this[K key] { get { Element item = ElementSearch(key); if (item != null) return item.val; throw new Exception($"Der Schlüssel {key} wurde nicht gefunden!"); } set { Element item = ElementSearch(key); if (item != null) // Existiert der Schlüssel schon in der Liste? item.val = value; // JA: Wert zurückliefern else AddEnd(key, value); // NEIN: Neues Schlüssel|Wert-Objekt der Liste hinzufügen } } //public int CompareTo(KeyValueListe other) //{ // throw new NotImplementedException(); //} } }