2009-03-09 13 views
28

Me doy cuenta de que C# y .NET en general ya tienen las clases Hashtable y Dictionary.¿Qué es un ejemplo de implementación de Hashtable en C#?

¿Alguien puede demostrar en C# una implementación de una Hashtable?

Actualización: Para aclarar, no estoy ncessarily en busca de una aplicación completa, sólo un ejemplo de las características principales de una tabla hash (es decir, añadir, eliminar encuentran por tecla).

+0

Sé que es una vieja pregunta, pero en realidad me he molestado en implementar una HashTable simple en 62 líneas de código que agrega y busca. – RichardOD

+3

en 2015 puede encontrarlo [aquí] (http://referencesource.microsoft.com/#mscorlib/system/collections/hashtable.cs) –

+0

@mt_serg: una lectura impresionante. Gracias por señalar eso. –

Respuesta

8

¿Has mirado el C5 collections? Puede download the source que incluye una tabla hash.

+0

Gracias por el enlace. Esperaba un pequeño ejemplo básico de Agregar/Eliminar con el módulo de hash incluido, pero no estoy seguro de si eso llenará toda la página –

2

Puede ver un simple 'crecer sólo' tabla hash here, que debe dar una idea de una implementación simple.

responsabilidad: Probablemente hay algunos errores en el código, pero el principio es el mismo :)

94

Mucho después de que la pregunta se ha hecho, por lo que no se puede esperar a ganar mucho rep. Sin embargo, decidí que sería divertido escribir mi propio ejemplo muy básico (en menos de 90 líneas de código):

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; 
     } 
    } 

He aquí una pequeña aplicación de prueba:

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(); 
     } 

No es la mejor aplicación, pero funciona para Agregar, Eliminar y Buscar. Utiliza chaining y un algoritmo de módulo simple para encontrar el depósito apropiado.

+1

Soy consciente de que esta pregunta y respuesta son bastante antiguas, pero tomaré este largo alcance. ¿No debería insertar \ delete \ find operaciones de O (n) eficiencia? – vondip

+3

no ..encontrar es solo O (n) el peor caso (todas las claves hash con el mismo valor ... no muy probable jeje), pero el caso esperado es constante. Insertar y Eliminar son constantes ya que solo crea el hash e lo inserta/quita de ese índice en la matriz ... no hay iteración sobre los elementos. – alexD

+2

Claro que puedes ver las implementaciones del mundo real de las colecciones basadas en Hash, pero este ejemplo es claro y excelente para entender el algoritmo. Hace hincapié en el uso de GetHashCode y Equals métodos que es muy importante para comprender la mecánica de HashMap. Muchas gracias por esta respuesta. –

Cuestiones relacionadas