/** * TreeMultiSet (ordered multiset) — a restricted, native-like API backed by RedBlackTree. * * Design goals: * - No node exposure * - Strict default comparator (number/string/Date), otherwise require comparator * - Default iteration is expanded (each element yielded `count(x)` times) * - `delete(x)` removes one occurrence by default */ import type { Comparator, TreeMultiSetOptions } from '../../types'; export declare class TreeMultiSet implements Iterable { #private; private _size; /** * Creates a new TreeMultiSet. * @param elements - Initial elements to add, or raw elements if `toElementFn` is provided. * @param options - Configuration options including optional `toElementFn` to transform raw elements. * @remarks Time O(m log m), Space O(m) where m is the number of initial elements * @example * // Standard usage with elements * const mset = new TreeMultiSet([1, 2, 2, 3]); * * // Using toElementFn to transform raw objects * const items = [{ score: 100 }, { score: 200 }, { score: 100 }]; * const mset = new TreeMultiSet(items, { toElementFn: item => item.score }); */ constructor(elements?: Iterable | Iterable, options?: TreeMultiSetOptions); /** * Validates the key against the default comparator rules. * @remarks Time O(1), Space O(1) */ private _validateKey; /** * Validates that count is a non-negative safe integer. * @remarks Time O(1), Space O(1) */ private _validateCount; /** * Total occurrences (sumCounts). * @remarks Time O(1), Space O(1) */ get size(): number; /** * Number of distinct keys. * @remarks Time O(1), Space O(1) * @example * // Unique key count * const ms = new TreeMultiSet(); * ms.add(1, 3); * ms.add(2, 2); * console.log(ms.distinctSize); // 2; */ get distinctSize(): number; /** * Whether the multiset is empty. * @remarks Time O(1), Space O(1) * @example * // Check empty * console.log(new TreeMultiSet().isEmpty()); // true; */ isEmpty(): boolean; /** * Whether the multiset contains the given key. * @remarks Time O(log n), Space O(1) * @example * // Check existence * const ms = new TreeMultiSet(); * ms.add(1); * console.log(ms.has(1)); // true; * console.log(ms.has(2)); // false; */ has(key: K): boolean; /** * Returns the count of occurrences for the given key. * @remarks Time O(log n), Space O(1) * @example * // Get occurrence count * const ms = new TreeMultiSet(); * ms.add(1, 5); * console.log(ms.count(1)); // 5; */ count(key: K): number; /** * Add `n` occurrences of `key`. * @returns True if the multiset changed. * @remarks Time O(log n), Space O(1) * @example * // Add elements * const ms = new TreeMultiSet(); * ms.add(1); * ms.add(1); * ms.add(2); * console.log(ms.count(1)); // 2; * console.log(ms.size); // 3; */ add(key: K, n?: number): boolean; /** * Set count for `key` to exactly `n`. * @returns True if changed. * @remarks Time O(log n), Space O(1) * @example * // Set occurrence count * const ms = new TreeMultiSet(); * ms.setCount(1, 3); * console.log(ms.count(1)); // 3; */ setCount(key: K, n: number): boolean; /** * Delete `n` occurrences of `key` (default 1). * @returns True if any occurrence was removed. * @remarks Time O(log n), Space O(1) * @example * // Remove one occurrence * const ms = new TreeMultiSet(); * ms.add(1, 3); * ms.delete(1); * console.log(ms.count(1)); // 2; */ delete(key: K, n?: number): boolean; /** * Delete all occurrences of the given key. * @returns True if any occurrence was removed. * @remarks Time O(log n), Space O(1) * @example * // Remove all occurrences * const ms = new TreeMultiSet(); * ms.add(1, 3); * ms.deleteAll(1); * console.log(ms.has(1)); // false; */ deleteAll(key: K): boolean; /** * Iterates over distinct keys (each key yielded once). * @remarks Time O(n), Space O(1) * @example * // Iterate unique keys * const ms = new TreeMultiSet(); * ms.add(1, 2); * ms.add(2); * console.log([...ms.keysDistinct()]); // [1, 2]; */ keysDistinct(): IterableIterator; /** * Iterates over entries as [key, count] pairs. * @remarks Time O(n), Space O(1) * @example * // Iterate entries * const ms = new TreeMultiSet(); * ms.add(1, 2); * console.log([...ms.entries()].length); // > 0; */ entries(): IterableIterator<[K, number]>; /** * Expanded iteration (default). Each key is yielded `count(key)` times. * @remarks Time O(size), Space O(1) where size is total occurrences */ [Symbol.iterator](): Iterator; /** * Iterate over all elements with multiplicity (Set-compatible, alias for `[Symbol.iterator]`). * @remarks Each key is yielded `count(key)` times. Time O(size), Space O(1) per step. * @example * // Iterate with multiplicity * const ms = new TreeMultiSet(); * ms.add(1); ms.add(1); ms.add(2); ms.add(3); ms.add(3); ms.add(3); * console.log([...ms.keys()]); // [1, 1, 2, 3, 3, 3]; */ keys(): IterableIterator; /** * Iterate over all elements with multiplicity (Set-compatible, alias for `[Symbol.iterator]`). * @remarks Each key is yielded `count(key)` times. Time O(size), Space O(1) per step. * @example * // Iterate with multiplicity * const ms = new TreeMultiSet(); * ms.add(5); ms.add(5); ms.add(10); * console.log([...ms.values()]); // [5, 5, 10]; */ values(): IterableIterator; /** * Returns an array with all elements (expanded). * @remarks Time O(size), Space O(size) * @example * // All elements (with duplicates) * const ms = new TreeMultiSet(); * ms.add(1, 2); * ms.add(2); * console.log(ms.toArray()); // [1, 1, 2]; */ toArray(): K[]; /** * Returns an array with distinct keys only. * @remarks Time O(n), Space O(n) * @example * // Unique keys only * const ms = new TreeMultiSet(); * ms.add(1, 3); * ms.add(2); * console.log(ms.toDistinctArray()); // [1, 2]; */ toDistinctArray(): K[]; /** * Returns an array of [key, count] entries. * @remarks Time O(n), Space O(n) * @example * // Key-count pairs * const ms = new TreeMultiSet(); * ms.add(1, 2); * ms.add(3); * console.log(ms.toEntries()); // [[1, 2], [3, 1]]; */ toEntries(): Array<[K, number]>; /** * Expose comparator for advanced usage/testing (read-only). * @remarks Time O(1), Space O(1) */ get comparator(): Comparator; /** * Remove all elements from the multiset. * @remarks Time O(1), Space O(1) * @example * // Remove all * const ms = new TreeMultiSet(); * ms.add(1); * ms.clear(); * console.log(ms.isEmpty()); // true; */ clear(): void; /** * Returns the smallest key, or undefined if empty. * @remarks Time O(log n), Space O(1) * @example * // Smallest element * const ms = new TreeMultiSet(); * ms.add(3); * ms.add(1); * console.log(ms.first()); // 1; */ first(): K | undefined; /** * Returns the largest key, or undefined if empty. * @remarks Time O(log n), Space O(1) * @example * // Largest element * const ms = new TreeMultiSet(); * ms.add(1); * ms.add(3); * console.log(ms.last()); // 3; */ last(): K | undefined; /** * Removes all occurrences of the smallest key and returns it. * @remarks Time O(log n), Space O(1) * @example * // Remove and return smallest * const ms = new TreeMultiSet(); * ms.add(2); * ms.add(1); * console.log(ms.pollFirst()); // 1; * console.log(ms.has(1)); // false; */ pollFirst(): K | undefined; /** * Removes all occurrences of the largest key and returns it. * @remarks Time O(log n), Space O(1) * @example * // Remove and return largest * const ms = new TreeMultiSet(); * ms.add(1); * ms.add(3); * console.log(ms.pollLast()); // 3; */ pollLast(): K | undefined; /** * Returns the smallest key >= given key, or undefined. * @remarks Time O(log n), Space O(1) * @example * // Least key ≥ target * const ms = new TreeMultiSet(); * ms.add(10); * ms.add(20); * ms.add(30); * console.log(ms.ceiling(15)); // 20; */ ceiling(key: K): K | undefined; /** * Returns the largest key <= given key, or undefined. * @remarks Time O(log n), Space O(1) * @example * // Greatest key ≤ target * const ms = new TreeMultiSet(); * ms.add(10); * ms.add(20); * ms.add(30); * console.log(ms.floor(25)); // 20; */ floor(key: K): K | undefined; /** * Returns the smallest key > given key, or undefined. * @remarks Time O(log n), Space O(1) * @example * // Least key > target * const ms = new TreeMultiSet(); * ms.add(10); * ms.add(20); * console.log(ms.higher(10)); // 20; */ higher(key: K): K | undefined; /** * Returns the largest key < given key, or undefined. * @remarks Time O(log n), Space O(1) * @example * // Greatest key < target * const ms = new TreeMultiSet(); * ms.add(10); * ms.add(20); * console.log(ms.lower(20)); // 10; */ lower(key: K): K | undefined; /** * Iterates over distinct keys with their counts. * @remarks Time O(n), Space O(1) * @example * // Iterate * const ms = new TreeMultiSet(); * ms.add(1, 2); * ms.add(2); * const pairs: [number, number][] = []; * ms.forEach((k, c) => pairs.push([k, c])); * console.log(pairs); // [[1, 2], [2, 1]]; */ forEach(callback: (key: K, count: number) => void): void; /** * Creates a new TreeMultiSet with entries that match the predicate. * @remarks Time O(n log n), Space O(n) * @example * // Filter * const ms = new TreeMultiSet(); * ms.add(1, 3); * ms.add(2, 1); * ms.add(3, 2); * const filtered = ms.filter((k, c) => c > 1); * console.log([...filtered.keysDistinct()]); // [1, 3]; */ filter(predicate: (key: K, count: number) => boolean): TreeMultiSet; /** * Reduces the multiset to a single value. * @remarks Time O(n), Space O(1) * @example * // Aggregate * const ms = new TreeMultiSet(); * ms.add(1, 2); * ms.add(2, 3); * const sum = ms.reduce((acc, k, c) => acc + k * c, 0); * console.log(sum); // 8; */ reduce(callback: (accumulator: U, key: K, count: number) => U, initialValue: U): U; /** * Maps keys and counts to a new TreeMultiSet. * When multiple keys map to the same new key, counts are merged (added). * @remarks Time O(n log n), Space O(n) * @example * // Transform * const ms = new TreeMultiSet(); * ms.add(1, 2); * ms.add(2, 3); * const doubled = ms.map((k, c) => [k * 10, c] as [number, number]); * console.log([...doubled.keysDistinct()]); // [10, 20]; */ map(mapper: (key: K, count: number) => [K2, number], options?: { comparator?: Comparator; }): TreeMultiSet; /** * Creates an independent copy of this multiset. * @remarks Time O(n log n), Space O(n) * @example * // Order-statistic on BST * const tree = new TreeMultiSet([30, 10, 50, 20, 40], { enableOrderStatistic: true }); * console.log(tree.getByRank(0)); // 10; * console.log(tree.getByRank(4)); // 50; * console.log(tree.getRank(30)); // 2; */ getByRank(k: number): K | undefined; /** * Get the rank of a key in sorted order * @example * // Get the rank of a key in sorted order * const tree = new TreeMultiSet( * [10, 20, 30, 40, 50], * { enableOrderStatistic: true } * ); * console.log(tree.getRank(10)); // 0; // smallest → rank 0 * console.log(tree.getRank(30)); // 2; // 2 elements before 30 in tree order * console.log(tree.getRank(50)); // 4; // largest → rank 4 * console.log(tree.getRank(25)); // 2; */ getRank(key: K): number; /** * Get elements by rank range * @example * // Pagination by position in tree order * const tree = new TreeMultiSet( * [10, 20, 30, 40, 50, 60, 70, 80, 90], * { enableOrderStatistic: true } * ); * const pageSize = 3; * * // Page 1 * console.log(tree.rangeByRank(0, pageSize - 1)); // [10, 20, 30]; * // Page 2 * console.log(tree.rangeByRank(pageSize, 2 * pageSize - 1)); // [40, 50, 60]; * // Page 3 * console.log(tree.rangeByRank(2 * pageSize, 3 * pageSize - 1)); // [70, 80, 90]; */ rangeByRank(start: number, end: number): K[]; /** * Deep copy * @example * // Deep clone * const ms = new TreeMultiSet(); * ms.add(1, 3); * const copy = ms.clone(); * copy.deleteAll(1); * console.log(ms.has(1)); // true; */ clone(): TreeMultiSet; /** * Returns keys within the given range. * @remarks Time O(log n + k), Space O(k) where k is result size * @example * // Find in range * const ms = new TreeMultiSet(); * ms.add(10); * ms.add(20); * ms.add(30); * const result = ms.rangeSearch([15, 25]); * console.log(result.length); // 1; */ rangeSearch any>(range: [K, K], callback?: C): (C extends undefined ? K : ReturnType)[]; /** * Prints the internal tree structure (for debugging). * @remarks Time O(n), Space O(n) * @example * // Display * const ms = new TreeMultiSet(); * ms.add(1); * expect(() => ms.print()).not.toThrow(); */ print(): void; }