@lnear/ds
Version:
A collection of data structures for JavaScript and TypeScript
332 lines (331 loc) • 8.98 kB
JavaScript
const a = {
/**
* Throws an error indicating an attempt to access the value of a Nothing instance.
* @throws {Error} Throws an error with a specific message.
*/
FromJustIsNothing() {
throw new Error("Maybe: Attempted to access value of Nothing");
}
};
class o {
/**
* Constructs a Maybe instance.
* @param hasValue - Indicates whether the instance has a value.
* @param value - The value contained in the Maybe instance (if any).
*/
constructor(t, e) {
this.hasValue = t, this.value = e;
}
/**
* Checks if the Maybe instance is Nothing (has no value).
* @returns {boolean} True if the instance is Nothing, otherwise false.
*/
IsNothing() {
return !this.hasValue;
}
/**
* Checks if the Maybe instance is Just (has a value).
* @returns {boolean} True if the instance is Just, otherwise false.
*/
IsJust() {
return this.hasValue;
}
/**
* Creates a Maybe instance representing Nothing.
* @returns {Maybe<T>} A Maybe instance with no value.
*/
static Nothing() {
return new o(!1);
}
/**
* Creates a Maybe instance representing Just with a given value.
* @param value - The value to be contained in the Maybe instance.
* @returns {Maybe<T>} A Maybe instance with the provided value.
*/
static Just(t) {
return new o(!0, t);
}
/**
* Retrieves the value of a Just instance or throws an error if it's Nothing.
* Alias for FromJust method.
* @returns {T} The value contained in the Just instance.
* @throws {Error} If the instance is Nothing.
*/
ToChecked() {
return this.FromJust();
}
/**
* Checks if the Maybe instance is Nothing and throws an error if it is.
* @throws {Error} If the instance is Nothing.
*/
Check() {
this.IsNothing() && a.FromJustIsNothing();
}
/**
* Retrieves the value of a Just instance and sets it in the provided output object.
* @param out - An object to hold the value if the instance is Just.
* @returns {boolean} True if the instance is Just, otherwise false.
*/
To(t) {
return this.IsJust() ? (t.value = this.value, t.hasValue = !0, !0) : !1;
}
/**
* Retrieves the value of a Just instance or throws an error if it's Nothing.
* @returns {T} The value contained in the Just instance.
* @throws {Error} If the instance is Nothing.
*/
FromJust() {
return this.IsNothing() && a.FromJustIsNothing(), this.value;
}
/**
* Retrieves the value of a Just instance or returns a default value if it's Nothing.
* @param defaultValue - The default value to return if the instance is Nothing.
* @returns {T} The value of the instance if it's Just, otherwise the default value.
*/
FromMaybe(t) {
return this.hasValue ? this.value : t;
}
/**
* Compares two Maybe instances for equality.
* @param other - Another Maybe instance to compare with.
* @returns {boolean} True if both instances are equal, otherwise false.
*/
equals(t) {
return this.IsJust() === t.IsJust() && (!this.IsJust() || this.FromJust() === t.FromJust());
}
/**
* Compares two Maybe instances for inequality.
* @param other - Another Maybe instance to compare with.
* @returns {boolean} True if both instances are not equal, otherwise false.
*/
notEquals(t) {
return !this.equals(t);
}
}
const h = o.Nothing, r = o.Just;
class l {
constructor(t, e = h()) {
this.data = t, this.next = e;
}
}
class J {
constructor() {
this.head = h();
}
isEmpty() {
return this.head.IsNothing();
}
size() {
let t = 0, e = this.head;
for (; e.IsJust(); )
t++, e = e.FromJust().next;
return t;
}
append(t) {
const e = new l(t);
if (this.isEmpty()) {
this.head = r(e);
return;
}
let s = this.head;
for (; s.IsJust() && s.FromJust().next.IsJust(); )
s = s.FromJust().next;
s.FromJust().next = r(e);
}
insert(t, e) {
if (e < 0 || e > this.size())
throw new Error("Invalid position");
const s = new l(t);
if (e === 0)
s.next = this.head, this.head = r(s);
else {
let i = this.head, u = 0;
for (; i.IsJust() && u < e - 1; )
i = i.FromJust().next, u++;
s.next = i.FromJust().next, i.FromJust().next = r(s);
}
}
remove(t) {
if (t < 0 || t >= this.size())
throw new Error("Invalid position");
if (t === 0)
this.head = this.head.FromJust().next;
else {
let e = this.head, s = 0;
for (; e.IsJust() && s < t - 1; )
e = e.FromJust().next, s++;
e.FromJust().next = e.FromJust().next.FromJust().next;
}
}
print() {
let t = this.head;
for (; t.IsJust(); )
console.log(t.FromJust().data), t = t.FromJust().next;
}
}
class m {
constructor(t, e = h(), s = h()) {
this.data = t, this.next = e, this.prev = s;
}
}
class c {
constructor() {
this.head = h(), this.tail = h();
}
isEmpty() {
return this.head.IsNothing();
}
size() {
let t = 0, e = this.head;
for (; e.IsJust(); )
t++, e = e.FromJust().next;
return t;
}
append(t) {
const e = new m(t);
if (this.isEmpty()) {
this.head = r(e), this.tail = r(e);
return;
}
const s = this.tail.FromJust();
s.next = r(e), e.prev = r(s), this.tail = r(e);
}
insert(t, e) {
if (e < 0 || e > this.size())
throw new Error("Invalid position");
const s = new m(t);
if (e === 0)
s.next = this.head, this.head.IsJust() && (this.head.FromJust().prev = r(s)), this.head = r(s);
else {
let i = this.head, u = 0;
for (; i.IsJust() && u < e - 1; )
i = i.FromJust().next, u++;
s.next = i.FromJust().next, s.prev = i, i.FromJust().next.IsJust() && (i.FromJust().next.FromJust().prev = r(s)), i.FromJust().next = r(s);
}
s.next.IsNothing() && (this.tail = r(s));
}
remove(t) {
if (t < 0 || t >= this.size())
throw new Error("Invalid position");
if (t === 0)
this.head = this.head.FromJust().next, this.head.IsJust() ? this.head.FromJust().prev = h() : this.tail = h();
else {
let e = this.head, s = 0;
for (; e.IsJust() && s < t; )
e = e.FromJust().next, s++;
e.IsJust() && (e.FromJust().prev.FromJust().next = e.FromJust().next, e.FromJust().next.IsJust() ? e.FromJust().next.FromJust().prev = e.FromJust().prev : this.tail = e.FromJust().prev);
}
}
print() {
let t = this.head;
for (; t.IsJust(); )
console.log(t.FromJust().data), t = t.FromJust().next;
}
}
class d {
constructor(t, e = h(), s = h()) {
this.data = t, this.left = e, this.right = s;
}
}
class F {
constructor() {
this.root = h();
}
insert(t) {
const e = new d(t);
this.root.IsNothing() ? this.root = r(e) : this.insertNode(this.root.FromJust(), e);
}
insertNode(t, e) {
e.data < t.data ? t.left.IsNothing() ? t.left = r(e) : this.insertNode(t.left.FromJust(), e) : t.right.IsNothing() ? t.right = r(e) : this.insertNode(t.right.FromJust(), e);
}
remove(t) {
this.root = this.removeNode(this.root, t);
}
removeNode(t, e) {
if (t.IsNothing())
return t;
const s = t.FromJust();
if (e < s.data)
return s.left = this.removeNode(s.left, e), r(s);
if (e > s.data)
return s.right = this.removeNode(s.right, e), r(s);
{
if (s.left.IsNothing() && s.right.IsNothing())
return h();
if (s.left.IsNothing())
return s.right;
if (s.right.IsNothing())
return s.left;
const i = this.findMinNode(s.right.FromJust());
return s.data = i.data, s.right = this.removeNode(s.right, i.data), r(s);
}
}
findMinNode(t) {
return t.left.IsNothing() ? t : this.findMinNode(t.left.FromJust());
}
search(t) {
return this.searchNode(this.root, t);
}
searchNode(t, e) {
if (t.IsNothing())
return !1;
const s = t.FromJust();
return e < s.data ? this.searchNode(s.left, e) : e > s.data ? this.searchNode(s.right, e) : !0;
}
inOrderTraverse(t) {
this.inOrderTraverseNode(this.root, t);
}
inOrderTraverseNode(t, e) {
if (t.IsNothing())
return;
const s = t.FromJust();
this.inOrderTraverseNode(s.left, e), e(s.data), this.inOrderTraverseNode(s.right, e);
}
}
class f {
constructor() {
this.items = [];
}
enqueue(t) {
this.items.push(t);
}
dequeue() {
return this.items.shift();
}
peek() {
return this.items[0];
}
isEmpty() {
return this.items.length === 0;
}
size() {
return this.items.length;
}
}
class N {
constructor() {
this.items = [];
}
push(t) {
this.items.push(t);
}
pop() {
return this.items.pop();
}
peek() {
return this.items[this.items.length - 1];
}
isEmpty() {
return this.items.length === 0;
}
size() {
return this.items.length;
}
}
export {
F as BinarySearchTree,
c as DoublyLinkedList,
J as LinkedList,
f as Queue,
N as Stack
};