Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class HashMap {
- constructor(initialCapacity=8) {
- this.length = 0;
- this._slots = [];
- this._capacity = initialCapacity;
- this._deleted = 0;
- }
- get(key) {
- const index = this._findSlot(key);
- if (this._slots[index] === undefined) {
- throw new Error('Key error');
- }
- return this._slots[index].value;
- }
- set(key, value) {
- const loadRatio = (this.length + this._deleted + 1) / this._capacity;
- if (loadRatio > HashMap.MAX_LOAD_RATIO) {
- this._resize(this._capacity * HashMap.SIZE_RATIO);
- }
- const index = this._findSlot(key);
- var linkedList = new LinkedList();
- this.length++;
- }
- remove(key) {
- const index = this._findSlot(key);
- const slot = this._slots[index];
- if (slot === undefined) {
- throw new Error('Key error');
- }
- slot.deleted = true;
- this.length--;
- this._deleted++;
- }
- _findSlot(key) {
- const hash = HashMap._hashString(key);
- const start = hash % this._capacity;
- for (let i=start; i<start + this._capacity; i++) {
- const index = i % this._capacity;
- const slot = this._slots[index];
- if (slot === undefined || (slot.key == key && !slot.deleted)) {
- return index;
- }
- }
- }
- _resize(size) {
- const oldSlots = this._slots;
- this._capacity = size;
- // Reset the length - it will get rebuilt as you add the items back
- this.length = 0;
- this._deleted = 0;
- this._slots = [];
- for (const slot of oldSlots) {
- if (slot !== undefined && !slot.deleted) {
- this.set(slot.key, slot.value);
- }
- }
- }
- static _hashString(string) {
- let hash = 5381;
- for (let i=0; i<string.length; i++) {
- hash = (hash << 5) + hash + string.charCodeAt(i);
- hash = hash & hash;
- }
- return hash >>> 0;
- }
- }
- HashMap.MAX_LOAD_RATIO = 0.9;
- HashMap.SIZE_RATIO = 3;
- class LinkedList {
- constructor() {
- this.length = 0;
- this.head = null;
- }
- insert(index, value) {
- if (index < 0 || index > this.length) {
- throw new Error('Index error');
- }
- const newNode = {
- value
- };
- if (index == 0) {
- newNode.next = this.head;
- this.head = newNode;
- }
- else {
- // Find the node which we want to insert after
- const node = this._find(index - 1);
- newNode.next = node.next;
- node.next = newNode;
- }
- this.length++;
- }
- _find(index) {
- let node = this.head;
- for (let i=0; i<index; i++) {
- node = node.next;
- }
- return node;
- }
- get(index) {
- if (index < 0 || index >= this.length) {
- throw new Error('Index error');
- }
- return this._find(index).value;
- }
- remove(index) {
- if (index < 0 || index >= this.length) {
- throw new Error('Index error');
- }
- if (index == 0) {
- this.head = this.head.next;
- }
- else {
- // Find the node before the one we want to remove
- const node = this._find(index - 1);
- node.next = node.next.next;
- }
- this.length--;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement