sussy-util
Version:
Util package made by me
213 lines (212 loc) • 8.7 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const Optional_1 = __importDefault(require("./Optional"));
class TreeNode {
constructor(value) {
this.value = value;
}
}
/**
* Represents a binary search tree.
* @template T - The type of elements stored in the tree.
*/
class Tree {
/**
* Creates a new Tree instance.
* @param {T} value - The value of the root node.
* @param {(a: T, b: T) => number} compareFunction - The function used to compare elements.
*/
constructor(value, compareFunction) {
/**
* Creates a new tree node with the given value.
* @param {T} value - The value of the node.
* @returns {TreeNode<T>} - The created tree node.
*/
this.createNode = (value) => {
return new TreeNode(value);
};
/**
* Inserts a new value into the tree.
* @param {T} value - The value to insert.
*/
this.insert = (value) => {
this.root = this.insertNode(this.root, value);
};
/**
* Recursively inserts a value into the tree.
* @param {TreeNode<T> | undefined} root - The root node of the subtree.
* @param {T} value - The value to insert.
* @returns {TreeNode<T>} - The updated root of the subtree.
*/
this.insertNode = (root, value) => {
if (!root)
return this.createNode(value);
const comparison = this.compare(value, root.value);
if (comparison < 0) {
root.left = this.insertNode(root.left, value);
}
else if (comparison > 0) {
root.right = this.insertNode(root.right, value);
}
return root;
};
/**
* Searches for a value in the tree.
* @param {T} value - The value to search for.
* @returns {Optional<TreeNode<T>>} - An Optional containing the found node or undefined.
*/
this.search = (value) => {
return Optional_1.default.ofNullable(this.searchNode(this.root, value));
};
/**
* Recursively searches for a value in the tree.
* @param {TreeNode<T> | undefined} root - The root node of the subtree.
* @param {T} value - The value to search for.
* @returns {TreeNode<T> | undefined} - The found node or undefined.
*/
this.searchNode = (root, value) => {
if (!root)
return undefined;
const comparison = this.compare(value, root.value);
if (comparison === 0)
return root;
if (comparison < 0)
return this.searchNode(root.left, value);
return this.searchNode(root.right, value);
};
/**
* Performs an in-order traversal of the tree, applying the callback to each node's value.
* @param {(value: T) => void} callback - The callback function to apply to each node's value.
*/
this.inOrderTraversal = (callback) => {
this.inOrderTraversalNode(this.root, callback);
};
/**
* Recursively performs an in-order traversal of the tree.
* @param {TreeNode<T> | undefined} root - The root node of the subtree.
* @param {(value: T) => void} callback - The callback function to apply to each node's value.
*/
this.inOrderTraversalNode = (root, callback) => {
if (!root)
return;
this.inOrderTraversalNode(root.left, callback);
callback(root.value);
this.inOrderTraversalNode(root.right, callback);
};
/**
* Performs a pre-order traversal of the tree, applying the callback to each node's value.
* @param {(value: T) => void} callback - The callback function to apply to each node's value.
*/
this.preOrderTraversal = (callback) => {
this.preOrderTraversalNode(this.root, callback);
};
/**
* Recursively performs a pre-order traversal of the tree.
* @param {TreeNode<T> | undefined} root - The root node of the subtree.
* @param {(value: T) => void} callback - The callback function to apply to each node's value.
*/
this.preOrderTraversalNode = (root, callback) => {
if (!root)
return;
callback(root.value);
this.preOrderTraversalNode(root.left, callback);
this.preOrderTraversalNode(root.right, callback);
};
/**
* Performs a post-order traversal of the tree, applying the callback to each node's value.
* @param {(value: T) => void} callback - The callback function to apply to each node's value.
*/
this.postOrderTraversal = (callback) => {
this.postOrderTraversalNode(this.root, callback);
};
/**
* Recursively performs a post-order traversal of the tree.
* @param {TreeNode<T> | undefined} root - The root node of the subtree.
* @param {(value: T) => void} callback - The callback function to apply to each node's value.
*/
this.postOrderTraversalNode = (root, callback) => {
if (!root)
return;
this.postOrderTraversalNode(root.left, callback);
this.postOrderTraversalNode(root.right, callback);
callback(root.value);
};
/**
* Finds the minimum value in the tree.
* @returns {Optional<TreeNode<T>>} - An Optional containing the node with the minimum value or undefined.
*/
this.findMin = () => {
let current = this.root;
while (current === null || current === void 0 ? void 0 : current.left)
current = current.left;
return Optional_1.default.ofNullable(current);
};
/**
* Finds the maximum value in the tree.
* @returns {Optional<TreeNode<T>>} - An Optional containing the node with the maximum value or undefined.
*/
this.findMax = () => {
let current = this.root;
while (current === null || current === void 0 ? void 0 : current.right)
current = current.right;
return Optional_1.default.ofNullable(current);
};
/**
* Removes a value from the tree if it exists.
* @param {T} value - The value to remove.
*/
this.remove = (value) => {
this.root = this.removeNode(this.root, value);
};
/**
* Recursively removes a node from the tree.
* @param {TreeNode<T> | undefined} root - The root node of the subtree.
* @param {T} value - The value to remove.
* @returns {TreeNode<T> | undefined} - The updated subtree root.
*/
this.removeNode = (root, value) => {
if (!root)
return undefined;
const comparison = this.compare(value, root.value);
if (comparison < 0) {
root.left = this.removeNode(root.left, value);
}
else if (comparison > 0) {
root.right = this.removeNode(root.right, value);
}
else {
// Value found
if (!root.left && !root.right)
return undefined;
if (!root.left)
return root.right;
if (!root.right)
return root.left;
// Node with two children: get the inorder successor
const successor = this.getMinNode(root.right);
if (successor) {
root.value = successor.value;
root.right = this.removeNode(root.right, successor.value);
}
}
return root;
};
/**
* Gets the node with the minimum value in the subtree.
* @param {TreeNode<T>} root - The root node of the subtree.
* @returns {TreeNode<T> | undefined} - The node with the minimum value.
*/
this.getMinNode = (root) => {
let current = root;
while (current === null || current === void 0 ? void 0 : current.left)
current = current.left;
return current;
};
this.compare = compareFunction;
this.root = this.createNode(value);
}
}
exports.default = Tree;