@sridhar-mani/dsa-js
Version:
A full-fledged data structure library with linked list and double linked list implementation
485 lines (477 loc) • 12.8 kB
JavaScript
class ComparerFunc {
constructor(compare) {
this.compare = compare || ComparerFunc.defaultCompareFunc;
}
static defaultCompareFunc(a, b) {
if (a === b)
return 0;
return a < b ? -1 : 1;
}
equal(a, b) {
return this.compare(a, b) === 0;
}
lessThan(a, b) {
return this.compare(a, b) < 0;
}
greaterThan(a, b) {
return this.compare(a, b) > 0;
}
lessThanOrEqual(a, b) {
return this.compare(a, b) <= 0;
}
greaterThanOrEqual(a, b) {
return this.compare(a, b) >= 0;
}
reverseCom() {
return new ComparerFunc((a, b) => this.compare(b, a));
}
}
class LLNode {
constructor(value, next = null) {
this.value = value;
this.next = next;
}
toString(callbackFunc) {
return callbackFunc ? callbackFunc(this.value) : `${this.value}`;
}
}
class LinkedList {
constructor(compareFunc) {
this.compare = new ComparerFunc(compareFunc);
this.head = null;
this.tail = null;
this.length = 0;
}
append(value) {
const newNode = new LLNode(value);
if (!this.head) {
this.head = this.tail = newNode;
}
else if (this.tail) {
this.tail.next = newNode;
this.tail = newNode;
}
this.length++;
return this;
}
prepend(value) {
const newNode = new LLNode(value, this.head);
this.head = newNode;
if (!this.tail) {
this.tail = newNode;
}
this.length++;
return this;
}
insert(value, indexTo) {
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 === null || currentNode === undefined ? undefined : 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;
}
getLength() {
return this.length;
}
delete(value) {
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;
}
find({ value, callback }) {
if (!this.head) {
return null;
}
let curNode = this.head;
while (curNode) {
if (callback === null || callback === undefined ? undefined : callback(curNode.value)) {
return curNode;
}
if (value !== undefined && this.compare.equal(curNode.value, value)) {
return curNode;
}
curNode = curNode.next;
}
return null;
}
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 === null || curNode === undefined ? undefined : curNode.next) !== this.tail) {
curNode = curNode.next;
}
curNode.next = null;
this.tail = curNode;
return deleteTail;
}
deleteHead() {
var _a;
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 = (_a = this.head) === null || _a === undefined ? undefined : _a.next;
return deleteHead;
}
getHead() {
if (this.head)
return this.head;
return null;
}
getTail() {
if (this.tail)
return this.tail;
return null;
}
fromArray(values) {
values.forEach(element => this.append(element));
return this;
}
toArray() {
const valuesList = [];
let curNode = this.head;
while (curNode) {
valuesList.push(curNode);
curNode = curNode.next;
}
return valuesList;
}
toString(callback) {
return this.toArray().map((m) => m.toString(callback)).toString();
}
reverse() {
let curNode = this.head;
let prevNode = null;
let nextNode = null;
while (curNode) {
nextNode = curNode.next;
curNode.next = prevNode;
prevNode = curNode;
curNode = nextNode;
}
this.tail = this.head;
this.head = prevNode;
return this;
}
clear() {
this.head = null;
this.tail = null;
this.length = 0;
return this;
}
}
class DoubleLLNode {
constructor(value, next = null, prev = null) {
this.value = value;
this.next = next;
this.prev = prev;
}
toString(callbackFunc) {
return callbackFunc ? callbackFunc(this.value) : `${this.value}`;
}
}
class DoubelLinkedList {
constructor(compareFunc) {
this.head = null;
this.tail = null;
this.compare = new ComparerFunc(compareFunc);
this.length = 0;
}
append(value) {
const newNode = new DoubleLLNode(value);
if (!this.head) {
this.head = this.tail = newNode;
}
else if (this.tail) {
this.tail.next = newNode;
this.tail = newNode;
}
this.length++;
return this;
}
prepend(value) {
const newNode = new DoubleLLNode(value);
this.head = newNode;
if (!this.tail) {
this.tail = newNode;
}
this.length++;
return this;
}
insert(value, indexTo) {
if (indexTo === 0) {
this.prepend(value);
this.length++;
return this;
}
else if (indexTo > (this.length - 1)) {
this.append(value);
this.length++;
return this;
}
else {
let temp = 0;
let curnode = this.head;
const newNode = new DoubleLLNode(value);
while (temp !== indexTo && curnode) {
curnode = curnode === null || curnode === undefined ? undefined : curnode.next;
temp++;
}
if (curnode) {
newNode.next = curnode;
newNode.prev = curnode.prev;
if (curnode.prev) {
curnode.prev.next = newNode;
}
else {
this.head = newNode;
}
curnode.prev = newNode;
this.length++;
return this;
}
}
return this;
}
getLength() {
return this.length;
}
delete(value) {
if (!this.head) {
return false;
}
if (this.head.value === value) {
if (this.head.next) {
this.head.next.prev = null;
this.head = this.head.next;
}
else {
this.head = null;
this.tail = null;
}
if (this.length > 0)
this.length--;
return true;
}
let curnode = this.head;
while (curnode) {
if (curnode.value === value) {
if (!curnode.next) {
this.tail = curnode.prev;
if (this.tail) {
this.tail.next = null;
}
}
else if (curnode.prev) {
curnode.prev.next = curnode.next;
curnode.next.prev = curnode.prev;
}
if (this.length > 0)
this.length--;
return true;
}
if (curnode.next)
curnode = curnode.next;
}
return false;
}
find({ value, callback }) {
if (!this.head) {
return null;
}
let curnode = this.head;
while (curnode) {
if (callback && callback(curnode.value)) {
return curnode;
}
if (value !== undefined && curnode.value === value) {
return curnode;
}
curnode = curnode.next;
}
return null;
}
deleteTail() {
if (!this.head)
return null;
let temp;
if (this.head === this.tail) {
temp = this.head;
this.tail = null;
this.head = null;
return temp;
}
let curnode = this.head;
while (curnode && curnode.next != this.tail) {
curnode = curnode.next;
}
if (curnode) {
temp = curnode.next;
curnode.next = null;
this.tail = curnode;
return temp;
}
return null;
}
deleteHead() {
if (!this.head)
return null;
const temp = this.head;
if (this.head === this.tail) {
this.tail = null;
this.head = null;
}
else {
this.head = this.head.next;
this.head.prev = null;
}
return temp;
}
fromArray(values) {
values.forEach(each => this.append(each));
return this;
}
toArray() {
const valuesList = [];
let curnode = this.head;
while (curnode) {
valuesList.push(curnode);
curnode = curnode.next;
}
return valuesList;
}
toString(callback) {
return this.toArray().map(each => callback ? callback(each.value) : String(each)).join(", ");
}
reverse() {
if (!this.head)
return null;
if (this.head === this.tail)
return this;
let curnode = this.head;
let prevnode = null;
let nextnode = null;
while (curnode) {
nextnode = curnode.next;
prevnode = curnode.prev;
curnode.next = prevnode;
curnode.prev = nextnode;
if (nextnode)
curnode = nextnode;
}
this.tail = this.head;
this.head = prevnode;
return this;
}
clear() {
this.head = null;
this.tail = null;
this.length = 0;
return this;
}
}
class StackMain {
constructor() {
this.linkedList = new LinkedList();
}
isEmpty() {
return !this.linkedList.getHead;
}
peek() {
if (!this.linkedList.getHead)
return null;
return this.linkedList.getHead();
}
push(value) {
this.linkedList.prepend(value);
}
pop(value) {
this.linkedList.append(value);
}
toArray() {
return this.linkedList.toArray();
}
toString(callBack) {
return this.linkedList.toString(callBack);
}
}
class QueueMain {
constructor() {
this.linkedList = new LinkedList();
}
isEmpty() {
return !(this.linkedList.getHead);
}
peek() {
if (!this.linkedList.getHead)
return null;
return this.linkedList.getHead;
}
enqueue(value) {
this.linkedList.append(value);
}
dequeue() {
const removedHead = this.linkedList.deleteHead();
return removedHead ? removedHead : null;
}
toString(callback) {
return this.linkedList.toString(callback);
}
}
export { ComparerFunc as CompareFunc, DoubelLinkedList, DoubleLLNode, LLNode, LinkedList, QueueMain, StackMain };
//# sourceMappingURL=linked-list-lib.esm.js.map