forked from keon/algorithms
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5fd9d6d
commit b7d5db1
Showing
4 changed files
with
154 additions
and
152 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
from .hashtable import * | ||
from .separate_chaining_hashtable import * |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
from algorithms.map import ( | ||
HashTable, ResizableHashTable, | ||
Node, SeparateChainingHashTable | ||
) | ||
|
||
import unittest | ||
|
||
class TestHashTable(unittest.TestCase): | ||
def test_one_entry(self): | ||
m = HashTable(10) | ||
m.put(1, '1') | ||
self.assertEqual('1', m.get(1)) | ||
|
||
def test_add_entry_bigger_than_table_size(self): | ||
m = HashTable(10) | ||
m.put(11, '1') | ||
self.assertEqual('1', m.get(11)) | ||
|
||
def test_get_none_if_key_missing_and_hash_collision(self): | ||
m = HashTable(10) | ||
m.put(1, '1') | ||
self.assertEqual(None, m.get(11)) | ||
|
||
def test_two_entries_with_same_hash(self): | ||
m = HashTable(10) | ||
m.put(1, '1') | ||
m.put(11, '11') | ||
self.assertEqual('1', m.get(1)) | ||
self.assertEqual('11', m.get(11)) | ||
|
||
def test_get_on_full_table_does_halts(self): | ||
# and does not search forever | ||
m = HashTable(10) | ||
for i in range(10, 20): | ||
m.put(i, i) | ||
self.assertEqual(None, m.get(1)) | ||
|
||
def test_delete_key(self): | ||
m = HashTable(10) | ||
for i in range(5): | ||
m.put(i, i**2) | ||
m.del_(1) | ||
self.assertEqual(None, m.get(1)) | ||
self.assertEqual(4,m.get(2)) | ||
|
||
def test_delete_key_and_reassign(self): | ||
m = HashTable(10) | ||
m.put(1, 1) | ||
del m[1] | ||
m.put(1, 2) | ||
self.assertEqual(2, m.get(1)) | ||
|
||
def test_assigning_to_full_table_throws_error(self): | ||
m = HashTable(3) | ||
m.put(1, 1) | ||
m.put(2, 2) | ||
m.put(3, 3) | ||
with self.assertRaises(ValueError): | ||
m.put(4, 4) | ||
|
||
def test_len_trivial(self): | ||
m = HashTable(10) | ||
self.assertEqual(0, len(m)) | ||
for i in range(10): | ||
m.put(i, i) | ||
self.assertEqual(i + 1, len(m)) | ||
|
||
def test_len_after_deletions(self): | ||
m = HashTable(10) | ||
m.put(1, 1) | ||
self.assertEqual(1, len(m)) | ||
m.del_(1) | ||
self.assertEqual(0, len(m)) | ||
m.put(11, 42) | ||
self.assertEqual(1, len(m)) | ||
|
||
def test_resizable_hash_table(self): | ||
m = ResizableHashTable() | ||
self.assertEqual(ResizableHashTable.MIN_SIZE, m.size) | ||
for i in range(ResizableHashTable.MIN_SIZE): | ||
m.put(i, 'foo') | ||
self.assertEqual(ResizableHashTable.MIN_SIZE * 2, m.size) | ||
self.assertEqual('foo', m.get(1)) | ||
self.assertEqual('foo', m.get(3)) | ||
self.assertEqual('foo', m.get(ResizableHashTable.MIN_SIZE - 1)) | ||
|
||
def test_fill_up_the_limit(self): | ||
m = HashTable(10) | ||
for i in range(10): | ||
m.put(i,i**2) | ||
for i in range(10): | ||
self.assertEqual(i**2,m.get(i)) | ||
|
||
|
||
class TestSeparateChainingHashTable(unittest.TestCase): | ||
def test_one_entry(self): | ||
m = SeparateChainingHashTable(10) | ||
m.put(1, '1') | ||
self.assertEqual('1', m.get(1)) | ||
|
||
def test_two_entries_with_same_hash(self): | ||
m = SeparateChainingHashTable(10) | ||
m.put(1, '1') | ||
m.put(11, '11') | ||
self.assertEqual('1', m.get(1)) | ||
self.assertEqual('11', m.get(11)) | ||
|
||
def test_len_trivial(self): | ||
m = SeparateChainingHashTable(10) | ||
self.assertEqual(0, len(m)) | ||
for i in range(10): | ||
m.put(i, i) | ||
self.assertEqual(i + 1, len(m)) | ||
|
||
def test_len_after_deletions(self): | ||
m = SeparateChainingHashTable(10) | ||
m.put(1, 1) | ||
self.assertEqual(1, len(m)) | ||
m.del_(1) | ||
self.assertEqual(0, len(m)) | ||
m.put(11, 42) | ||
self.assertEqual(1, len(m)) | ||
|
||
def test_delete_key(self): | ||
m = SeparateChainingHashTable(10) | ||
for i in range(5): | ||
m.put(i, i**2) | ||
m.del_(1) | ||
self.assertEqual(None, m.get(1)) | ||
self.assertEqual(4, m.get(2)) | ||
|
||
def test_delete_key_and_reassign(self): | ||
m = SeparateChainingHashTable(10) | ||
m.put(1, 1) | ||
del m[1] | ||
m.put(1, 2) | ||
self.assertEqual(2, m.get(1)) | ||
|
||
def test_add_entry_bigger_than_table_size(self): | ||
m = SeparateChainingHashTable(10) | ||
m.put(11, '1') | ||
self.assertEqual('1', m.get(11)) | ||
|
||
def test_get_none_if_key_missing_and_hash_collision(self): | ||
m = SeparateChainingHashTable(10) | ||
m.put(1, '1') | ||
self.assertEqual(None, m.get(11)) | ||
|
||
|
||
|
||
if __name__ == "__main__": | ||
unittest.main() |