UNPKG

@sridhar-mani/dsa-js

Version:

A full-fledged data structure library with linked list and double linked list implementation

228 lines (175 loc) 5.25 kB
import CompareFunc from '../util/compareFuncs' import LLNode from './llnode'; export default class LinkedList<T>{ private compare: CompareFunc<T>; private head: LLNode<T> | null; private tail: LLNode<T> | null; private length: number; constructor(compareFunc?: (a: T, b: T) => number){ this.compare = new CompareFunc<T>(compareFunc); this.head = null; this.tail=null this.length = 0; } public append(value: T):this{ const newNode = new LLNode<T>(value); if(!this.head){ this.head = this.tail= newNode }else if(this.tail){ this.tail.next = newNode; this.tail = newNode; } this.length++ return this } public prepend(value: T):this{ const newNode = new LLNode<T>(value,this.head); this.head = newNode; if(!this.tail){ this.tail = newNode } this.length++ return this } public insert(value:T,indexTo:number):this{ if(indexTo===0){ this.prepend(value) return this }else if(indexTo > (this.length-1)){ this.append(value) return this }else{ let temp = 0; let currentNode = this.head; const newNode = new LLNode(value); while(temp!==indexTo && currentNode){ currentNode = currentNode?.next; temp++; } if(currentNode){ newNode.next = currentNode.next; currentNode.next = newNode; return this }else{ if(this.tail){ this.tail.next = newNode; this.tail = newNode; }else{ this.head = newNode; this.tail = newNode; } } } return this } public getLength(){ return this.length; } public delete(value:any):void |null { if(!this.head){ return null } if(this.head.value===value){ this.head = this.head.next; this.length-- return } let curNode = this.head while(curNode.next){ if(curNode.next.value===value){ curNode.next=curNode.next.next this.length-- return } curNode=curNode.next } return null } public find({value,callback}:{value?:T, callback?:(val:T)=>boolean}):LLNode<T> | null{ if(!this.head){ return null } let curNode: LLNode<T> | null = this.head while(curNode ){ if(callback?.(curNode.value)){ return curNode } if(value!==undefined && this.compare.equal(curNode.value,value)){ return curNode } curNode = curNode.next } return null } public deleteTail(){ if(!this.head) return null const deleteTail = this.tail; if(this.tail===this.head){ this.head=null this.tail=null return deleteTail } let curNode = this.head; while( curNode.next && curNode?.next!==this.tail){ curNode=curNode.next } curNode.next=null this.tail =curNode return deleteTail } public deleteHead(){ if(!this.head) return null const deleteHead = this.head; if(this.head===this.tail){ this.head=null; this.tail=null return deleteHead } if(this.head) this.head = this.head?.next return deleteHead } public getHead(){ if(this.head) return this.head return null } public getTail(){ if(this.tail) return this.tail return null } public fromArray(values:Array<T>){ values.forEach(element => this.append(element)); return this } public toArray(){ const valuesList:LLNode<T>[]=[] let curNode = this.head while(curNode){ valuesList.push(curNode) curNode=curNode.next } return valuesList } public toString(callback:(value:T)=> string){ return this.toArray().map((m)=>m.toString(callback)).toString() } public reverse(){ let curNode = this.head; let prevNode:null | LLNode<T> = null; let nextNode:null | LLNode<T> = null; while(curNode){ nextNode = curNode.next curNode.next = prevNode prevNode = curNode curNode = nextNode } this.tail=this.head; this.head = prevNode return this } public clear(){ this.head=null this.tail=null this.length=0 return this } }