UNPKG

trie-typed

Version:
271 lines (270 loc) 11.1 kB
/** * data-structure-typed * * @author Pablo Zeng * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com> * @license MIT License */ import type { ElemOf, EntryCallback, RedBlackTreeOptions, TreeMultiMapOptions } from '../../types'; import { RedBlackTree, RedBlackTreeNode } from './red-black-tree'; import { IBinaryTree } from '../../interfaces'; /** * Node used by TreeMultiMap; stores the key with a bucket of values (array). * @remarks Time O(1), Space O(1) * @template K * @template V */ export declare class TreeMultiMapNode<K = any, V = any> extends RedBlackTreeNode<K, V[]> { parent?: TreeMultiMapNode<K, V>; /** * Create a TreeMultiMap node with an optional value bucket. * @remarks Time O(1), Space O(1) * @param key - Key of the node. * @param [value] - Initial array of values. * @returns New TreeMultiMapNode instance. */ constructor(key: K, value?: V[]); _left?: TreeMultiMapNode<K, V> | null | undefined; /** * Get the left child pointer. * @remarks Time O(1), Space O(1) * @returns Left child node, or null/undefined. */ get left(): TreeMultiMapNode<K, V> | null | undefined; /** * Set the left child and update its parent pointer. * @remarks Time O(1), Space O(1) * @param v - New left child node, or null/undefined. * @returns void */ set left(v: TreeMultiMapNode<K, V> | null | undefined); _right?: TreeMultiMapNode<K, V> | null | undefined; /** * Get the right child pointer. * @remarks Time O(1), Space O(1) * @returns Right child node, or null/undefined. */ get right(): TreeMultiMapNode<K, V> | null | undefined; /** * Set the right child and update its parent pointer. * @remarks Time O(1), Space O(1) * @param v - New right child node, or null/undefined. * @returns void */ set right(v: TreeMultiMapNode<K, V> | null | undefined); } /** * Red-Black Tree–based multimap (key array of values). Preserves O(log N) updates and supports map-like mode. * @remarks Time O(1), Space O(1) * @template K * @template V * @template R * @example * // players ranked by score with their equipment * type Equipment = { * name: string; // Equipment name * quality: 'legendary' | 'epic' | 'rare' | 'common'; * level: number; * }; * * type Player = { * name: string; * score: number; * equipments: Equipment[]; * }; * * // Mock player data with their scores and equipment * const players: Player[] = [ * { * name: 'DragonSlayer', * score: 8750, * equipments: [ * { name: 'AWM', quality: 'legendary', level: 85 }, * { name: 'Level 3 Helmet', quality: 'epic', level: 80 }, * { name: 'Extended Quickdraw Mag', quality: 'rare', level: 75 }, * { name: 'Compensator', quality: 'epic', level: 78 }, * { name: 'Vertical Grip', quality: 'rare', level: 72 } * ] * }, * { * name: 'ShadowNinja', * score: 7200, * equipments: [ * { name: 'M416', quality: 'epic', level: 75 }, * { name: 'Ghillie Suit', quality: 'rare', level: 70 }, * { name: 'Red Dot Sight', quality: 'common', level: 65 }, * { name: 'Extended QuickDraw Mag', quality: 'rare', level: 68 } * ] * }, * { * name: 'RuneMaster', * score: 9100, * equipments: [ * { name: 'KAR98K', quality: 'legendary', level: 90 }, * { name: 'Level 3 Vest', quality: 'legendary', level: 85 }, * { name: 'Holographic Sight', quality: 'epic', level: 82 }, * { name: 'Suppressor', quality: 'legendary', level: 88 }, * { name: 'Level 3 Backpack', quality: 'epic', level: 80 } * ] * }, * { * name: 'BattleKing', * score: 8500, * equipments: [ * { name: 'AUG', quality: 'epic', level: 82 }, * { name: 'Red Dot Sight', quality: 'rare', level: 75 }, * { name: 'Extended Mag', quality: 'common', level: 70 }, * { name: 'Tactical Stock', quality: 'rare', level: 76 } * ] * }, * { * name: 'SniperElite', * score: 7800, * equipments: [ * { name: 'M24', quality: 'legendary', level: 88 }, * { name: 'Compensator', quality: 'epic', level: 80 }, * { name: 'Scope 8x', quality: 'legendary', level: 85 }, * { name: 'Level 2 Helmet', quality: 'rare', level: 75 } * ] * }, * { * name: 'RushMaster', * score: 7500, * equipments: [ * { name: 'Vector', quality: 'rare', level: 72 }, * { name: 'Level 2 Helmet', quality: 'common', level: 65 }, * { name: 'Quickdraw Mag', quality: 'common', level: 60 }, * { name: 'Laser Sight', quality: 'rare', level: 68 } * ] * }, * { * name: 'GhostWarrior', * score: 8200, * equipments: [ * { name: 'SCAR-L', quality: 'epic', level: 78 }, * { name: 'Extended Quickdraw Mag', quality: 'rare', level: 70 }, * { name: 'Holographic Sight', quality: 'epic', level: 75 }, * { name: 'Suppressor', quality: 'rare', level: 72 }, * { name: 'Vertical Grip', quality: 'common', level: 65 } * ] * }, * { * name: 'DeathDealer', * score: 7300, * equipments: [ * { name: 'SKS', quality: 'epic', level: 76 }, * { name: 'Holographic Sight', quality: 'rare', level: 68 }, * { name: 'Extended Mag', quality: 'common', level: 65 } * ] * }, * { * name: 'StormRider', * score: 8900, * equipments: [ * { name: 'MK14', quality: 'legendary', level: 92 }, * { name: 'Level 3 Backpack', quality: 'legendary', level: 85 }, * { name: 'Scope 8x', quality: 'epic', level: 80 }, * { name: 'Suppressor', quality: 'legendary', level: 88 }, * { name: 'Tactical Stock', quality: 'rare', level: 75 } * ] * }, * { * name: 'CombatLegend', * score: 7600, * equipments: [ * { name: 'UMP45', quality: 'rare', level: 74 }, * { name: 'Level 2 Vest', quality: 'common', level: 67 }, * { name: 'Red Dot Sight', quality: 'common', level: 62 }, * { name: 'Extended Mag', quality: 'rare', level: 70 } * ] * } * ]; * * // Create a TreeMultiMap for player rankings * const playerRankings = new TreeMultiMap<number, Equipment, Player>(players, { * toEntryFn: ({ score, equipments }) => [score, equipments], * isMapMode: false * }); * * const topPlayersEquipments = playerRankings.rangeSearch([8900, 10000], node => playerRankings.get(node)); * console.log(topPlayersEquipments); // [ * // [ * // { * // name: 'MK14', * // quality: 'legendary', * // level: 92 * // }, * // { name: 'Level 3 Backpack', quality: 'legendary', level: 85 }, * // { * // name: 'Scope 8x', * // quality: 'epic', * // level: 80 * // }, * // { name: 'Suppressor', quality: 'legendary', level: 88 }, * // { * // name: 'Tactical Stock', * // quality: 'rare', * // level: 75 * // } * // ], * // [ * // { name: 'KAR98K', quality: 'legendary', level: 90 }, * // { * // name: 'Level 3 Vest', * // quality: 'legendary', * // level: 85 * // }, * // { name: 'Holographic Sight', quality: 'epic', level: 82 }, * // { * // name: 'Suppressor', * // quality: 'legendary', * // level: 88 * // }, * // { name: 'Level 3 Backpack', quality: 'epic', level: 80 } * // ] * // ] */ export declare class TreeMultiMap<K = any, V = any, R extends object = object> extends RedBlackTree<K, V[], R> implements IBinaryTree<K, V[], R> { /** * Create a TreeMultiMap and optionally bulk-insert items. * @remarks Time O(N log N), Space O(N) * @param [keysNodesEntriesOrRaws] - Iterable of keys/nodes/entries/raw items to insert. * @param [options] - Options for TreeMultiMap (comparator, reverse, map mode). * @returns New TreeMultiMap instance. */ constructor(keysNodesEntriesOrRaws?: Iterable<K | TreeMultiMapNode<K, V> | [K | null | undefined, V[] | undefined] | null | undefined | R>, options?: TreeMultiMapOptions<K, V[], R>); _createNode(key: K, value?: V[]): TreeMultiMapNode<K, V>; add(keyNodeOrEntry: K | TreeMultiMapNode<K, V> | [K | null | undefined, V[] | undefined] | null | undefined): boolean; add(key: K, value: V): boolean; /** * Delete a single value from the bucket at a given key. Removes the key if the bucket becomes empty. * @remarks Time O(log N), Space O(1) * @param keyNodeOrEntry - Key, node, or [key, values] entry to locate the bucket. * @param value - Value to remove from the bucket. * @returns True if the value was removed; false if not found. */ deleteValue(keyNodeOrEntry: K | TreeMultiMapNode<K, V> | [K | null | undefined, V[] | undefined] | null | undefined, value: V): boolean; map<MK = K, MVArr extends unknown[] = V[], MR extends object = object>(callback: EntryCallback<K, V[] | undefined, [MK, MVArr]>, options?: Partial<RedBlackTreeOptions<MK, MVArr, MR>>, thisArg?: unknown): TreeMultiMap<MK, ElemOf<MVArr>, MR>; map<MK = K, MV = V[], MR extends object = object>(callback: EntryCallback<K, V[] | undefined, [MK, MV]>, options?: Partial<RedBlackTreeOptions<MK, MV, MR>>, thisArg?: unknown): RedBlackTree<MK, MV, MR>; /** * (Protected) Create an empty instance of the same concrete class. * @remarks Time O(1), Space O(1) * @template TK * @template TV * @template TR * @param [options] - Optional constructor options for the like-kind instance. * @returns An empty like-kind instance. */ protected _createInstance<TK = K, TV = V, TR extends object = R>(options?: Partial<RedBlackTreeOptions<TK, TV, TR>>): this; /** * (Protected) Create a like-kind instance and seed it from an iterable. * @remarks Time O(N log N), Space O(N) * @template TK * @template TV * @template TR * @param iter - Iterable used to seed the new tree. * @param [options] - Options merged with the current snapshot. * @returns A like-kind RedBlackTree built from the iterable. */ protected _createLike<TK = K, TV = V, TR extends object = R>(iter?: Iterable<TK | RedBlackTreeNode<TK, TV> | [TK | null | undefined, TV | undefined] | null | undefined | TR>, options?: Partial<RedBlackTreeOptions<TK, TV, TR>>): RedBlackTree<TK, TV, TR>; }