UNPKG

sussy-util

Version:
213 lines (212 loc) 8.7 kB
"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;