Skip to content

Commit a24f2e8

Browse files
committed
Implement:
HashTableLinearProbing HashTableSeparateChaining
1 parent 5efe61e commit a24f2e8

File tree

6 files changed

+315
-34
lines changed

6 files changed

+315
-34
lines changed

TODO.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
Here is Data Structures base on https://en.wikipedia.org/wiki/List_of_data_structures
44

5-
6-
75
## Data Structures
86

97
### Abstract data types
@@ -18,7 +16,9 @@ Here is Data Structures base on https://en.wikipedia.org/wiki/List_of_data_struc
1816
- [x] Queue (example Priority queue)
1917
- [ ] Double-ended queue
2018
- [ ] Graph (example Tree, Heap)
21-
- [ ] Hash Table
19+
- [x] Hash Table
20+
- [x] Linear Probing Technique
21+
- [x] Separate Chaining Technique
2222
- [ ] Dictionary
2323

2424
### Linear
@@ -74,7 +74,7 @@ Here is Data Structures base on https://en.wikipedia.org/wiki/List_of_data_struc
7474
-[ ] Dynamic perfect hash table
7575
-[ ] Hash array mapped trie
7676
-[ ] Hash list
77-
-[ ] Hash table
77+
-[x] Hash table
7878
-[ ] Hash tree
7979
-[ ] Hash trie
8080
-[ ] Koorde

src/ConsoleApp/Program.cs

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using DataStructures.AbstractDataTypes.Arrays;
2+
using DataStructures.AbstractDataTypes.Hashes;
23
using DataStructures.AbstractDataTypes.Lists;
34
using DataStructures.AbstractDataTypes.Queues;
45
using DataStructures.AbstractDataTypes.Stacks;
@@ -12,20 +13,40 @@
1213
//StackUsage();
1314
//LinkedListStackUsage();
1415
//LinedListQueueUsage();
15-
HashSetUsage();
16+
//HashSetUsage();
17+
//HashTableSeparateChainingUsage();
18+
HashTableLinearProbingUsage();
1619

1720

21+
22+
void HashTableLinearProbingUsage()
23+
{
24+
var hashTable = new HashTableLinearProbing<int>(2);
25+
for (var i = 0; i < 50; i++)
26+
{
27+
hashTable.Add(i);
28+
}
29+
Console.WriteLine($"Table Count:{hashTable.Count}");
30+
foreach (var item in hashTable)
31+
{
32+
Console.WriteLine($"Item:{item}");
33+
}
34+
hashTable.Remove(2);
35+
hashTable.Contains(2);
36+
Console.WriteLine($"Table New Count:{hashTable.Count}");
37+
}
38+
1839
void ArrayUsage()
1940
{
20-
SimpleArray.Sort(new[] {7, 5, 3, 9});
41+
SimpleArray.Sort(new[] { 7, 5, 3, 9 });
2142
}
2243

2344
void ArrayListUsage()
2445
{
2546
var arrayList = new ArrayList();
2647
arrayList.Add("Item 1");
2748
arrayList.Add(2);
28-
var exists = arrayList.Contains(2);
49+
var exists = arrayList.Contains(2);
2950
Console.WriteLine($"Element 2 Exists: {exists}");
3051
}
3152

@@ -38,7 +59,7 @@ void ListUsage()
3859
3,
3960
4
4061
};
41-
62+
4263
foreach (var item in list)
4364
{
4465
Console.WriteLine(item);
@@ -114,7 +135,7 @@ void LinedListQueueUsage()
114135
queue.Enqueue(2);
115136
queue.Enqueue(3);
116137
queue.Enqueue(4);
117-
138+
118139
var first = queue.Peek();
119140
var e1 = queue.Dequeue();
120141
var e2 = queue.Dequeue();
@@ -134,4 +155,20 @@ void HashSetUsage()
134155

135156
var isExist = set.Contains("Name 2");
136157
//set.Remove("Name 2");
158+
}
159+
160+
void HashTableSeparateChainingUsage()
161+
{
162+
var hashTable = new HashTableSeparateChaining<int>(4);
163+
for (var i = 0; i < 50; i++)
164+
{
165+
hashTable.Add(i);
166+
}
167+
Console.Write($"Table Count:{hashTable.Count}");
168+
foreach (var item in hashTable)
169+
{
170+
Console.WriteLine(item);
171+
}
172+
173+
var exists = hashTable.Contains(4);
137174
}

src/DataStructures/AbstractDataTypes/Hashes/HashSet.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ private void Resize()
4848
var newSize = _capacity * 2;
4949
Resize(newSize);
5050
}
51+
5152
private void Resize(int newSize)
5253
{
5354
var newEntries = new Entry[newSize];
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
using System.Collections;
2+
3+
namespace DataStructures.AbstractDataTypes.Hashes;
4+
5+
public class HashTableLinearProbing<T> : IEnumerable<T>
6+
{
7+
private class Item
8+
{
9+
public readonly T Data;
10+
11+
public Item(T data)
12+
{
13+
Data = data;
14+
}
15+
}
16+
17+
private int _size;
18+
private int _free;
19+
private Item?[] _entries;
20+
public int Count { get; private set; }
21+
22+
public HashTableLinearProbing()
23+
{
24+
_size = 20;
25+
_free = _size;
26+
_entries = new Item[_size];
27+
}
28+
29+
public HashTableLinearProbing(int size)
30+
{
31+
_size = size;
32+
_free = size;
33+
_entries = new Item[_size];
34+
}
35+
36+
private static int GetHash(T item)
37+
{
38+
return item!.GetHashCode();
39+
}
40+
41+
private int GetHashIndex(T item)
42+
{
43+
return GetHash(item) % _size;
44+
}
45+
46+
public bool Contains(T data)
47+
{
48+
var index = GetHashIndex(data);
49+
var comparer = EqualityComparer<T>.Default;
50+
51+
for (var i = 0; i < _size; i++)
52+
{
53+
var index2 = (i + index) % _size;
54+
var item = _entries[index2];
55+
if (item is not null && comparer.Equals(item.Data, data))
56+
return true;
57+
}
58+
59+
return false;
60+
}
61+
62+
public void Remove(T data)
63+
{
64+
var index = GetHashIndex(data);
65+
var comparer = EqualityComparer<T>.Default;
66+
67+
for (var i = 0; i < _size; i++)
68+
{
69+
var index2 = (i + index) % _size;
70+
var item = _entries[index2];
71+
if (item is not null && !comparer.Equals(item.Data, data)) continue;
72+
73+
_entries[index2] = null;
74+
Count--;
75+
return;
76+
}
77+
}
78+
79+
public bool Add(T data)
80+
{
81+
if (Contains(data))
82+
return false;
83+
84+
if (_free <= 0)
85+
Expand();
86+
87+
var index = GetHashIndex(data);
88+
for (var i = 0; i < _size; i++)
89+
{
90+
var index2 = (i + index) % _size;
91+
if (_entries[index2] is not null) continue;
92+
93+
_entries[index2] = new Item(data);
94+
Count++;
95+
_free--;
96+
return true;
97+
}
98+
99+
return false;
100+
}
101+
102+
private void Expand()
103+
{
104+
var newSize = _size * 2;
105+
var newEntries = new Item?[newSize];
106+
var newFree = newSize;
107+
var count = 0;
108+
for (var i = 0; i < _size; i++)
109+
{
110+
var item = _entries[i];
111+
if(item is null)
112+
continue;
113+
114+
var hash = GetHash(item.Data);
115+
var index = hash % newSize;
116+
for (var j = 0; j < newSize; j++)
117+
{
118+
var index2 = (j + index) % newSize;
119+
if (newEntries[index2] is not null) continue;
120+
121+
newEntries[index2] = item;
122+
count++;
123+
newFree--;
124+
break;
125+
}
126+
}
127+
128+
_size = newSize;
129+
_entries = newEntries;
130+
_free = newFree;
131+
Count = count;
132+
}
133+
134+
public IEnumerator<T> GetEnumerator()
135+
{
136+
for (var i = 0; i < _size; i++)
137+
{
138+
var item = _entries[i];
139+
if (item is not null)
140+
yield return item.Data;
141+
}
142+
}
143+
144+
IEnumerator IEnumerable.GetEnumerator()
145+
{
146+
return GetEnumerator();
147+
}
148+
}

0 commit comments

Comments
 (0)