Add HashTable.

This commit is contained in:
Oleksii Trekhleb
2018-03-28 09:29:47 +03:00
parent 97b8765a7d
commit ce40b52e09
9 changed files with 250 additions and 24 deletions

View File

@@ -0,0 +1,36 @@
import LinkedList from '../linked-list/LinkedList';
const defaultHashTableSize = 32;
export default class HashTable {
constructor(hashTableSize = defaultHashTableSize) {
// Create hash table of certain size and fill each bucket with empty linked list.
this.buckets = Array(hashTableSize).fill(null).map(() => new LinkedList());
}
// Converts key string to hash number.
hash(key) {
const hash = Array.from(key).reduce(
(hashAccumulator, keySymbol) => (hashAccumulator + keySymbol.charCodeAt(0)),
0,
);
// Reduce hash number so it would fit hash table size.
return hash % this.buckets.length;
}
insert(key, value) {
const bucketLinkedList = this.buckets[this.hash(key)];
bucketLinkedList.appendUnique({ key, value });
}
delete(key) {
const bucketLinkedList = this.buckets[this.hash(key)];
return bucketLinkedList.deleteByKey(key);
}
get(key) {
const bucketLinkedList = this.buckets[this.hash(key)];
return bucketLinkedList.findByKey(key);
}
}

View File

@@ -0,0 +1,9 @@
# Hashed Table
|Operation |Complexity |
|---------------------------|-------------------|
|Find |O(1)* |
|Insert |O(1)* |
|Delete |O(1)* |
* - assuming that we have "good" hash function and big enough hash table size so that collisions are rare.

View File

@@ -0,0 +1,49 @@
import HashTable from '../HashTable';
describe('HashTable', () => {
it('should create hash table of certain size', () => {
const defaultHashTable = new HashTable();
expect(defaultHashTable.buckets.length).toBe(32);
const biggerHashTable = new HashTable(64);
expect(biggerHashTable.buckets.length).toBe(64);
});
it('should generate proper hash for specified keys', () => {
const hashTable = new HashTable();
expect(hashTable.hash('a')).toBe(1);
expect(hashTable.hash('b')).toBe(2);
expect(hashTable.hash('abc')).toBe(6);
});
it('should insert, read and delete data with collisions', () => {
const hashTable = new HashTable(3);
expect(hashTable.hash('a')).toBe(1);
expect(hashTable.hash('b')).toBe(2);
expect(hashTable.hash('c')).toBe(0);
expect(hashTable.hash('d')).toBe(1);
hashTable.insert('a', 'sky-old');
hashTable.insert('a', 'sky');
hashTable.insert('b', 'sea');
hashTable.insert('c', 'earth');
hashTable.insert('d', 'ocean');
expect(hashTable.buckets[0].toString()).toBe('c:earth');
expect(hashTable.buckets[1].toString()).toBe('a:sky,d:ocean');
expect(hashTable.buckets[2].toString()).toBe('b:sea');
expect(hashTable.get('a').value).toBe('sky');
expect(hashTable.get('d').value).toBe('ocean');
hashTable.delete('a');
expect(hashTable.get('a')).toBeNull();
expect(hashTable.get('d').value).toBe('ocean');
hashTable.insert('d', 'ocean-new');
expect(hashTable.get('d').value).toBe('ocean-new');
});
});