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;
}
}