我正在尝试在C#中实现哈希表。这是我到目前为止所做的:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GenericHashMap.hashtable
{
class GenericHashtable<T>
{
private List<Node<T>> array;
private int capacity;
public GenericHashtable(int capacity)
{
this.capacity = capacity;
array = new List<Node<T>>(capacity);
for (int i = 0; i < capacity; i++)
{
array.Insert(i, null);
}
}
public class Node<E>
{
private E info;
private Node<E> next;
public Node(E info, Node<E> next)
{
this.info = info;
this.next = next;
}
public E Info
{
get
{
return this.info;
}
set
{
this.info = value;
}
}
public Node<E> Next
{
get
{
return this.next;
}
set
{
this.next = value;
}
}
}
public bool IsEmpty()
{
if (array.Count == 0)
{
return true;
}
return false;
}
public void Add(T element)
{
int index = Math.Abs(element.GetHashCode() % capacity);
Node<T> ToAdd = new Node<T>(element, null);
Console.WriteLine("index = " + index);
if (array.ElementAt(index) == null)
{
array.Insert(index, ToAdd);
Console.WriteLine("The element " + array.ElementAt(index).Info.ToString() + " was found at index " + index);
}
else
{
Node<T> cursor = array.ElementAt(index);
while (cursor.Next != null)
{
cursor = cursor.Next;
}
if (cursor.Next == null)
{
cursor.Next = ToAdd;
Console.WriteLine("The element " + array.ElementAt(index).Info.ToString() + " was found at index " + index);
}
}
}
public bool Search(T key)
{
int index = Math.Abs(key.GetHashCode() % capacity);
Console.WriteLine("Index = " + index);
Console.WriteLine("The element " + array.ElementAt(index).Info.ToString());
if (array.ElementAt(index) == null)
{
return false;
}
else
{
if (array.ElementAt(index).Equals(key))
{
Console.WriteLine("The element " + key + "exists in the map at index " + index);
return true;
}
else
{
Node<T> cursor = array.ElementAt(index);
while (cursor != null && !(cursor.Info.Equals(key)))
{
cursor = cursor.Next;
}
if (cursor.Info.Equals(key))
{
Console.WriteLine("The " + key + "exists in the map");
return true;
}
}
}
return false;
}
public void PrintElements()
{
for (int i = 0; i < capacity; i++)
{
Node<T> cursor = array.ElementAt(i);
while (cursor != null)
{
Console.WriteLine(cursor.Info.ToString());
cursor = cursor.Next;
}
}
}
}
}
现在,我在表格中添加以下字符串:
GenericHashtable<string> table = new GenericHashtable<string>(11);
table.Add("unu"); -> index 3
table.Add("doi"); -> index 0
table.Add("trei"); -> index 6
table.Add("patru"); -> index 7
table.Add("cinci"); -> index 2
table.Add("sase"); -> index 0
现在,一切都很好,添加了元素。但是当我试图搜索元素“unu”时,它找不到因为它的索引不再是3,它是5.“trei”的索引不是6,它是7 ...我不明白为什么元素正在改变它们的索引。我想在Add()方法中添加元素时出现了问题,但我无法弄明白自己是什么。有什么答案吗?
答案 0 :(得分:1)
这是您Add
方法中的问题:
array.Insert(index, ToAdd);
您的array
变量实际上不是数组 - 它是一个列表。而且你正在中插入元素,而不仅仅是设置现有元素。这将影响所有具有后期索引的现有元素 - 增加其索引。
我建议改用数组,然后使用索引器:
private Node<T>[] nodes;
然后:
Node<T> node = nodes[index];
if (node == null)
{
nodes[index] = newNode;
}
...
(说实话还有其他各种奇怪的问题,但这就是当前问题的原因。)