-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathOpenAddressHasingHashTable.cs
More file actions
119 lines (95 loc) · 3.92 KB
/
OpenAddressHasingHashTable.cs
File metadata and controls
119 lines (95 loc) · 3.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
using System;
namespace AlgorithmsAndDataStructures.DataStructures.HashTable;
public class OpenAddressHasingHashTable<TKey, TValue>
{
private static readonly HashEntry<TKey, TValue> DeletedEntry = new()
{
Key = default,
Value = default
};
private readonly HashEntry<TKey, TValue>[] hashTable;
private int counter;
public OpenAddressHasingHashTable(int initialCapacity = 8)
{
hashTable = new HashEntry<TKey, TValue>[initialCapacity];
counter = 0;
}
public void Add(TKey key, TValue value)
{
if (counter == hashTable.Length && !Find(key)) throw new ArgumentException("Hash table is full.");
var initialIndex = Math.Abs(key.GetHashCode() % hashTable.Length);
var currentIndex = initialIndex;
do
{
if (hashTable[currentIndex] == DeletedEntry || hashTable[currentIndex] == null)
{
hashTable[currentIndex] = new HashEntry<TKey, TValue>
{
Value = value,
Key = key
};
break;
}
#pragma warning disable HAA0601 // Value type to reference type conversion causing boxing allocation
if (hashTable[currentIndex].Key.Equals(key))
#pragma warning restore HAA0601 // Value type to reference type conversion causing boxing allocation
{
hashTable[currentIndex].Value = value;
break;
}
currentIndex = (currentIndex + 1) % hashTable.Length;
} while (currentIndex != initialIndex);
counter += 1;
}
public bool Find(TKey key)
{
var initialIndex = Math.Abs(key.GetHashCode() % hashTable.Length);
var currentIndex = initialIndex;
do
{
if (hashTable[currentIndex] == null) return false;
#pragma warning disable HAA0601 // Value type to reference type conversion causing boxing allocation
if (hashTable[currentIndex].Key?.Equals(key) == true)
#pragma warning restore HAA0601 // Value type to reference type conversion causing boxing allocation
return true;
currentIndex = (currentIndex + 1) % hashTable.Length;
} while (currentIndex != initialIndex);
return false;
}
public TValue Get(TKey key)
{
var initialIndex = Math.Abs(key.GetHashCode() % hashTable.Length);
var currentIndex = initialIndex;
do
{
if (hashTable[currentIndex] == null)
throw new ArgumentException($"Hash table has no entry with key {key}.");
#pragma warning disable HAA0601 // Value type to reference type conversion causing boxing allocation
if (hashTable[currentIndex].Key?.Equals(key) == true)
#pragma warning restore HAA0601 // Value type to reference type conversion causing boxing allocation
return hashTable[currentIndex].Value;
currentIndex = (currentIndex + 1) % hashTable.Length;
} while (currentIndex != initialIndex);
throw new ArgumentException($"Hash table has no entry with key {key}.");
}
public void Delete(TKey key)
{
var initialIndex = Math.Abs(key.GetHashCode() % hashTable.Length);
var currentIndex = initialIndex;
do
{
if (hashTable[currentIndex] == null)
// Nothing to delete.
return;
#pragma warning disable HAA0601 // Value type to reference type conversion causing boxing allocation
if (hashTable[currentIndex] != DeletedEntry && hashTable[currentIndex].Key.Equals(key))
#pragma warning restore HAA0601 // Value type to reference type conversion causing boxing allocation
{
hashTable[currentIndex] = DeletedEntry;
counter -= 1;
return;
}
currentIndex = (currentIndex + 1) % hashTable.Length;
} while (currentIndex != initialIndex);
}
}