2009-03-09 11 views
28

Ich weiß, C# und .NET im Allgemeinen bereits die Hashtable und Dictionary-Klassen.Was ist ein Beispiel für eine Hashtable-Implementierung in C#?

Kann jemand in C# eine Implementierung einer Hashtable demonstrieren?

Update: Um zu verdeutlichen, bin ich nicht unbedingt auf der Suche nach einer vollständigen Implementierung, nur ein Beispiel für die Kernfunktionen einer Hashtable (d. H. Hinzufügen, entfernen, finden nach Schlüssel).

+0

Ich weiß, dass es eine alte Frage ist, aber ich habe mich wirklich bemüht, eine einfache HashTable in 62 Codezeilen zu implementieren, die Hinzufügen und Finden. – RichardOD

+3

im Jahr 2015 finden Sie es [hier] (http://referencesource.microsoft.com/#mscorlib/system/collections/hashtable.cs) –

+0

@ Mt_serg: eine tolle Lese. Danke für den Hinweis. –

Antwort

8

Haben Sie sich die C5 collections angesehen? Sie können download the source, die eine Hash-Tabelle enthält.

+0

Danke für den Link. Ich hoffte auf ein kleines grundlegendes Beispiel für Hinzufügen/Entfernen mit dem Hashing modulo einschließlich, aber nicht sicher, ob das die gesamte Seite füllen wird –

2

Sie können eine einfache Ansicht 'wachsen-only' hashtable here, die Ihnen eine Idee geben sollte einer einfachen Implementierung.

Haftungsausschluss: Es gibt wahrscheinlich ein paar Fehler im Code, aber das Prinzip ist das gleiche :)

94

Lange nachdem die Frage gestellt worden, so erwarte ich nicht viel rep zu verdienen. Allerdings habe ich beschlossen, es würde Spaß machen, mein eigenes sehr einfaches Beispiel (in weniger als 90 Zeilen Code) zu schreiben:

public struct KeyValue<K, V> 
    { 
     public K Key { get; set; } 
     public V Value { get; set; } 
    } 

    public class FixedSizeGenericHashTable<K,V> 
    { 
     private readonly int size; 
     private readonly LinkedList<KeyValue<K,V>>[] items; 

     public FixedSizeGenericHashTable(int size) 
     { 
      this.size = size; 
      items = new LinkedList<KeyValue<K,V>>[size]; 
     } 

     protected int GetArrayPosition(K key) 
     { 
      int position = key.GetHashCode() % size; 
      return Math.Abs(position); 
     } 

     public V Find(K key) 
     { 
      int position = GetArrayPosition(key); 
      LinkedList<KeyValue<K, V>> linkedList = GetLinkedList(position); 
      foreach (KeyValue<K,V> item in linkedList) 
      { 
       if (item.Key.Equals(key)) 
       { 
        return item.Value; 
       } 
      } 

      return default(V); 
     } 

     public void Add(K key, V value) 
     { 
      int position = GetArrayPosition(key); 
      LinkedList<KeyValue<K, V>> linkedList = GetLinkedList(position); 
      KeyValue<K, V> item = new KeyValue<K, V>() { Key = key, Value = value }; 
      linkedList.AddLast(item); 
     } 

     public void Remove(K key) 
     { 
      int position = GetArrayPosition(key); 
      LinkedList<KeyValue<K, V>> linkedList = GetLinkedList(position); 
      bool itemFound = false; 
      KeyValue<K, V> foundItem = default(KeyValue<K, V>); 
      foreach (KeyValue<K,V> item in linkedList) 
      { 
       if (item.Key.Equals(key)) 
       { 
        itemFound = true; 
        foundItem = item; 
       } 
      } 

      if (itemFound) 
      { 
       linkedList.Remove(foundItem); 
      } 
     } 

     protected LinkedList<KeyValue<K, V>> GetLinkedList(int position) 
     { 
      LinkedList<KeyValue<K, V>> linkedList = items[position]; 
      if (linkedList == null) 
      { 
       linkedList = new LinkedList<KeyValue<K, V>>(); 
       items[position] = linkedList; 
      } 

      return linkedList; 
     } 
    } 

Hier ist eine kleine Testanwendung:

static void Main(string[] args) 
     { 
      FixedSizeGenericHashTable<string, string> hash = new FixedSizeGenericHashTable<string, string>(20); 

      hash.Add("1", "item 1"); 
      hash.Add("2", "item 2"); 
      hash.Add("dsfdsdsd", "sadsadsadsad"); 

      string one = hash.Find("1"); 
      string two = hash.Find("2"); 
      string dsfdsdsd = hash.Find("dsfdsdsd"); 
      hash.Remove("1"); 
      Console.ReadLine(); 
     } 

Es ist nicht die beste Umsetzung, aber es funktioniert für Hinzufügen, Entfernen und Suchen. Es verwendet chaining und einen einfachen Modulo-Algorithmus, um den passenden Bucket zu finden.

+1

Ich bin mir bewusst, dass diese Frage und Antwort ziemlich alt sind, aber ich werde diesen Longshot nehmen. Sollte das Einfügen von \ delete \ find-Operationen nicht O (n) -effizient sein? – vondip

+3

nein ..Finden ist nur O (n) schlimmsten Fall (alle Schlüssel Hash auf den gleichen Wert .. nicht sehr wahrscheinlich hehe), aber der Fall ist konstant. Einfügen und Löschen sind beide konstant, da Sie einfach den Hash erstellen und ihn aus diesem Index in das Array einfügen/entfernen. Es gibt keine Iteration über die Elemente. – alexD

+2

Sicher können Sie reale Implementierungen von Hash-basierten Sammlungen betrachten, aber dieses Beispiel ist sauber und großartig, um den Algorithmus zu verstehen. Es betont die Verwendung der Methoden GetHashCode und Equals, was sehr wichtig ist, um die Mechanik von HashMap zu verstehen. Vielen Dank für diese Antwort. –

Verwandte Themen