Skip to content

Commit 9a64614

Browse files
authored
Merge pull request aalhour#125 from Gutsonok/master
Fixed aalhour#117 and one more bug in ChainedHashTable
2 parents 1cc477e + b26b11e commit 9a64614

File tree

2 files changed

+145
-120
lines changed

2 files changed

+145
-120
lines changed

DataStructures/Dictionaries/ChainedHashTable.cs

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ public enum CapacityManagementMode
3434
private decimal _slotsLoadFactor;
3535
private const int _defaultCapacity = 8;
3636
private DLinkedList<TKey, TValue>[] _hashTableStore;
37-
private static readonly DLinkedList<TKey, TValue>[] _emptyArray = new DLinkedList<TKey, TValue>[_defaultCapacity];
3837
private List<TKey> _keysCollection { get; set; }
3938
private List<TValue> _valuesCollection { get; set; }
4039

@@ -56,7 +55,7 @@ public enum CapacityManagementMode
5655
public ChainedHashTable()
5756
{
5857
this._size = 0;
59-
this._hashTableStore = _emptyArray;
58+
this._hashTableStore = new DLinkedList<TKey, TValue>[_defaultCapacity];
6059
this._freeSlotsCount = this._hashTableStore.Length;
6160
this._keysComparer = EqualityComparer<TKey>.Default;
6261
this._valuesComparer = EqualityComparer<TValue>.Default;
@@ -442,7 +441,7 @@ public void Add(TKey key, TValue value)
442441
// Decrease the number of free slots.
443442
_freeSlotsCount--;
444443
}
445-
else if (_hashTableStore[hashcode] != null && _hashTableStore[hashcode].Count > 0)
444+
else if (_hashTableStore[hashcode].Count > 0)
446445
{
447446
if (_hashTableStore[hashcode].ContainsKey(key) == true)
448447
throw new ArgumentException("Key already exists in the hash table.");
@@ -582,7 +581,7 @@ public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
582581

583582
int i = arrayIndex;
584583
int hashTableIndex = 0;
585-
int countOfElements = (array.Length - arrayIndex);
584+
var currentChainNode = new DLinkedListNode<TKey, TValue>();
586585

587586
while (true)
588587
{
@@ -591,30 +590,19 @@ public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
591590
if (i >= array.Length)
592591
break;
593592

594-
if (_hashTableStore[hashTableIndex] != null && _hashTableStore[hashTableIndex].Count > 0)
593+
if (_hashTableStore[hashTableIndex] != null)
595594
{
596-
if (_hashTableStore[hashTableIndex].Count == 1)
595+
currentChainNode = _hashTableStore[hashTableIndex].Head;
596+
while (currentChainNode != null && i < array.Length)
597597
{
598-
pair = new KeyValuePair<TKey, TValue>(_hashTableStore[hashTableIndex].First.Key, _hashTableStore[hashTableIndex].First.Value);
598+
pair = new KeyValuePair<TKey, TValue>(currentChainNode.Key, currentChainNode.Value);
599599
array[i] = pair;
600600
i++;
601601
hashTableIndex++;
602-
}
603-
else
604-
{
605-
var headOfChain = _hashTableStore[hashTableIndex].Head;
606-
607-
while (i < array.Length)
608-
{
609-
pair = new KeyValuePair<TKey, TValue>(headOfChain.Key, headOfChain.Value);
610-
array[i] = pair;
611-
i++;
612-
hashTableIndex++;
613602

614-
headOfChain = headOfChain.Next;
615-
}
616-
}//end-if-else
617-
}//end-if
603+
currentChainNode = currentChainNode.Next;
604+
}
605+
}
618606
else
619607
{
620608
hashTableIndex++;
@@ -631,7 +619,7 @@ public void Clear()
631619
Array.Clear(_hashTableStore, 0, _hashTableStore.Length);
632620

633621
// Re-initialize to empty collection.
634-
_hashTableStore = _emptyArray;
622+
_hashTableStore = new DLinkedList<TKey, TValue>[_defaultCapacity];
635623

636624
_size = 0;
637625
_slotsLoadFactor = 0;
Lines changed: 134 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
24
using DataStructures.Dictionaries;
35
using Xunit;
46

@@ -7,107 +9,142 @@ namespace UnitTest.DataStructuresTests
79
public static class HashTableSeparateChainingTest
810
{
911
[Fact]
10-
public static void DoTest()
12+
public static void Adding_ThreeDifferentElements_ReturnsSuccessful()
1113
{
12-
// TEST ADD KEY-VALUE PAIRS
13-
var studentsMarks = new ChainedHashTable<string, int>
14-
{
15-
{"Konstantinos", 124},
16-
{"Bic", 224},
17-
{"Z", 324},
18-
{"Ioanna", 424},
19-
{"Mark Zuckerberg", 524},
20-
{"Semsem", 624},
21-
{"Sa3eeed", 724},
22-
{"Sameer", 824},
23-
{"Ahmad", 924},
24-
{"Zeyad", 999},
25-
{"Mahmoood 3eed", 111},
26-
{"Mahmoood Abu 3eed", 222},
27-
{"EISA", 333},
28-
{"Test1", 3210},
29-
{"Test11", 3210},
30-
{"Test222", 3210},
31-
{"Test3333", 3210},
32-
{"Test44444", 3210},
33-
{"Test555555", 3210},
34-
{"Test6666666", 3210},
35-
{"Test77777777", 3210},
36-
{"Test888888888", 3210}
37-
};
38-
39-
// TEST FETCH KEY-VALUE
40-
var mark = studentsMarks["Ahmad"];
41-
Assert.True(mark == 924);
42-
43-
mark = studentsMarks["Konstantinos"];
44-
Assert.True(mark == 124);
45-
46-
mark = studentsMarks["Bic"];
47-
Assert.True(mark == 224);
48-
49-
mark = studentsMarks["Z"];
50-
Assert.True(mark == 324);
51-
52-
mark = studentsMarks["Ioanna"];
53-
Assert.True(mark == 424);
54-
55-
mark = studentsMarks["Mark Zuckerberg"];
56-
Assert.True(mark == 524);
57-
58-
mark = studentsMarks["Semsem"];
59-
Assert.True(mark == 624);
60-
61-
mark = studentsMarks["Sa3eeed"];
62-
Assert.True(mark == 724);
63-
64-
mark = studentsMarks["Sameer"];
65-
Assert.True(mark == 824);
66-
67-
mark = studentsMarks["Zeyad"];
68-
Assert.True(mark == 999);
69-
70-
mark = studentsMarks["Mahmoood 3eed"];
71-
Assert.True(mark == 111);
72-
73-
mark = studentsMarks["Mahmoood Abu 3eed"];
74-
Assert.True(mark == 222);
75-
76-
mark = studentsMarks["EISA"];
77-
Assert.True(mark == 333);
78-
79-
//
80-
// TEST DELETE BY KEYS
81-
studentsMarks.Remove("Ahmad");
82-
studentsMarks.Remove("Zeyad");
83-
studentsMarks.Remove("Bic");
84-
studentsMarks.Remove("Konstantinos");
85-
studentsMarks.Remove("Sameer");
86-
studentsMarks.Remove("Z");
87-
studentsMarks.Remove("Ioanna");
88-
studentsMarks.Remove("Mark Zuckerberg");
89-
studentsMarks.Remove("Semsem");
90-
studentsMarks.Remove("Sa3eeed");
91-
studentsMarks.Remove("Test1");
92-
studentsMarks.Remove("Test11");
93-
studentsMarks.Remove("Test222");
94-
studentsMarks.Remove("Test3333");
95-
studentsMarks.Remove("Test44444");
96-
studentsMarks.Remove("Test555555");
97-
studentsMarks.Remove("Test6666666");
98-
studentsMarks.Remove("Test77777777");
99-
studentsMarks.Remove("Test888888888");
14+
var studentsMarks = new ChainedHashTable<string, int>();
15+
16+
studentsMarks.Add("Name1", 1);
17+
studentsMarks.Add("Name2", 5);
18+
studentsMarks.Add(new KeyValuePair<string, int>("Name3", 3));
19+
20+
var mark = studentsMarks["Name1"];
21+
Assert.True(mark == 1);
22+
23+
mark = studentsMarks["Name2"];
24+
Assert.True(mark == 5);
25+
26+
mark = studentsMarks["Name3"];
27+
Assert.True(mark == 3);
10028

10129
Assert.True(studentsMarks.Count == 3);
30+
}
31+
32+
[Fact]
33+
public static void Adding_TwoDuplicateElements_ReturnsException()
34+
{
35+
var studentsMarks = new ChainedHashTable<string, int>();
36+
studentsMarks.Add("Name1", 1);
37+
studentsMarks.Add("Name2", 5);
38+
39+
Action act = () => studentsMarks.Add("Name2", 7);
40+
41+
var exception = Assert.Throws<ArgumentException>(act);
42+
Assert.Equal("Key already exists in the hash table.", exception.Message);
43+
Assert.True(studentsMarks.Count == 2);
44+
}
45+
46+
[Fact]
47+
public static void GetElement_ExistingElement_ReturnsElement()
48+
{
49+
var studentsMarks = new ChainedHashTable<string, int>();
50+
studentsMarks.Add("Name1", 1);
51+
studentsMarks.Add("Name2", 5);
10252

103-
KeyValuePair<string, int>[] array = new KeyValuePair<string, int>[studentsMarks.Count];
104-
105-
if (studentsMarks != null)
106-
{
107-
studentsMarks.CopyTo(array, 0);
108-
}
53+
var value = studentsMarks["Name2"];
54+
55+
Assert.Equal(5, value);
56+
Assert.True(studentsMarks.Count == 2);
57+
}
58+
59+
[Fact]
60+
public static void GetElement_NonExistingElement_ReturnsException()
61+
{
62+
var studentsMarks = new ChainedHashTable<string, int>();
63+
studentsMarks.Add("Name1", 1);
64+
studentsMarks.Add("Name2", 5);
65+
66+
int value;
67+
Action act = () => value = studentsMarks["Name3"];
68+
69+
Assert.Throws<KeyNotFoundException>(act);
70+
Assert.True(studentsMarks.Count == 2);
71+
}
72+
73+
[Fact]
74+
public static void RemovingOneElement_ThreeDifferentElements_ReturnsSuccessful()
75+
{
76+
var studentsMarks = new ChainedHashTable<string, int>();
77+
studentsMarks.Add("Name1", 1);
78+
studentsMarks.Add("Name2", 5);
79+
studentsMarks.Add(new KeyValuePair<string, int>("Name3", 3));
10980

110-
Assert.True(array.Length == studentsMarks.Count);
81+
studentsMarks.Remove("Name2");
82+
83+
var mark = studentsMarks["Name1"];
84+
Assert.True(mark == 1);
85+
86+
mark = studentsMarks["Name3"];
87+
Assert.True(mark == 3);
88+
89+
Assert.False(studentsMarks.ContainsKey("Name2"));
90+
91+
Assert.True(studentsMarks.Count == 2);
92+
}
93+
94+
[Fact]
95+
public static void RemovingAllElement_ThreeDifferentElements_ReturnsSuccessful()
96+
{
97+
var studentsMarks = new ChainedHashTable<string, int>();
98+
studentsMarks.Add("Name1", 1);
99+
studentsMarks.Add("Name2", 5);
100+
studentsMarks.Add(new KeyValuePair<string, int>("Name3", 3));
101+
102+
studentsMarks.Remove("Name2");
103+
studentsMarks.Remove("Name1");
104+
studentsMarks.Remove("Name3");
105+
106+
Assert.True(studentsMarks.Count == 0);
107+
}
108+
109+
[Fact]
110+
public static void CopyTo_FilledHashTable_ReturnsSuccessful()
111+
{
112+
var studentsMarks = new ChainedHashTable<string, int>();
113+
studentsMarks.Add("Name1", 1);
114+
studentsMarks.Add("Name2", 5);
115+
studentsMarks.Add(new KeyValuePair<string, int>("Name3", 3));
116+
117+
var array = new KeyValuePair<string, int>[studentsMarks.Count];
118+
studentsMarks.CopyTo(array, 0);
119+
120+
Assert.True(studentsMarks.Count == 3);
121+
Assert.True(array.Length == 3);
122+
var arrayKeys = array.Select(x => x.Key).OrderBy(x => x).ToArray();
123+
Assert.Equal("Name1", arrayKeys[0]);
124+
Assert.Equal("Name2", arrayKeys[1]);
125+
Assert.Equal("Name3", arrayKeys[2]);
126+
var arrayValues = array.Select(x => x.Value).OrderBy(x => x).ToArray();
127+
Assert.Equal(1, arrayValues[0]);
128+
Assert.Equal(3, arrayValues[1]);
129+
Assert.Equal(5, arrayValues[2]);
130+
131+
}
132+
133+
[Fact]
134+
public static void CopyTo_EmptyHashTable_ReturnsSuccessful()
135+
{
136+
var studentsMarks = new ChainedHashTable<string, int>();
137+
studentsMarks.Add("Name1", 1);
138+
studentsMarks.Add("Name2", 5);
139+
studentsMarks.Add(new KeyValuePair<string, int>("Name3", 3));
140+
141+
studentsMarks.Remove("Name2");
142+
studentsMarks.Remove("Name1");
143+
studentsMarks.Remove("Name3");
144+
145+
Assert.True(studentsMarks.Count == 0);
146+
var array = new KeyValuePair<string, int>[studentsMarks.Count];
147+
studentsMarks.CopyTo(array, 0);
111148
}
112149
}
113150
}

0 commit comments

Comments
 (0)