function defaultToString(item){ if(item == null){ return 'null'; } if(item == undefined){ return 'undefined'; } if(typeof item == "string" || item instanceof String){ return `${item}`; } return item.toString(); } class ValuePair{ constructor(key,value){ this.key = key; this.value = value; } } class Node{ constructor(element,next){ this.element = element; this.next = next; } } class LinkedList{ constructor(){ this.head = undefined; this.count = 0; } isEmpty(){ return this.size() == 0; } size(){ return this.count; } push(element){ let node = new Node(element); if(this.head == undefined){ this.head = node; }else{ let current = this.head; while(current.next!=null){ current = current.next; } current.next = node; } this.count++; } remove(element){ let index = this.indexOf(element); this.removeAt(index); } removeAt(index){ if(index>=0 && index < this.count){ let current = this.head; if(index == 0){ if(this.count == 1){ this.head = undefined; }else{ this.head = current.next; } }else{ let previous = this.getElementAt(index - 1); current = previous.next; previous.next = current.next; } this.count--; } return '' } getHead(){ if(this.head!=undefined){ return this.head; } return 'null'; } indexOf(element){ let current = this.head; for(let i =0; i < this.count; i++){ if(current.element === element){ return i; } current = current.next; } } getElementAt(index){ if(index>=0 && index< this.count){ let current = this.head; for(let i = 0; i < index; i++){ current = current.next; } return current; } return -1; } insert(element,position){ if(position >= 0&& position <= this.count){ let node = new Node(element); let previous = this.getElementAt(position - 1); if(position == 0){ if(this.head == undefined){ this.head = node; }else{ node.next = this.head; this.head = node; } }else if(position == this.count){ previous.next = node; }else{ let current = previous.next; node.next = current; previous.next = node; } this.count++; } return '' } toString(){ let current = this.head.next; let objString = this.head.element; for(let i = 1; i < this.count; i++){ objString = `${objString},${current.element}`; } return objString; } } class HashTableSpeparateChaining{ constructor(toStrFn = defaultToString){ this.toStrFn = toStrFn; this.table = {}; } loseloseHashCode(key){ if(typeof key == 'number'){ return key; } let str = this.toStrFn(key); let addr = 0; for(let i = 0; i < str.length;i++){ addr += str.charCodeAt(i); } return addr % 37; } hashCode(key){ return this.loseloseHashCode(key); } put(key,value){ if(key != null && value != null){ let valuePair =new ValuePair(key,value); const position = this.hashCode(key); if(this.table[position] == null){ this.table[position] = new LinkedList(); } this.table[position].push(valuePair); return true; } return false; } get(key){ const position = this.hashCode(key); const linkedList = this.table[position]; if(linkedList != null && !linkedList.isEmpty()){ let current = linkedList.getHead(); while(current!=null){ if(current.element.key == key){ return current.element.value; } current = current.next; } } return undefined; } remove(key){ const position = this.hashCode(key); const linkedList = this.table[position]; if(this.table[position] != null && !linkedList.isEmpty()){ let current = linkedList.getHead(); let previous = null; for(let i = 0 ; i < linkedList.size(); i++){ if(current.element.key == key){ if(previous == null){ linkedList.head = current.next; }else{ previous.next = current.next; } } previous = current; current = current.next; } return true; } return false; } }