data-structure-typed 2.5.1 → 2.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. package/CHANGELOG.md +5 -1
  2. package/MIGRATION.md +169 -0
  3. package/README.md +135 -23
  4. package/README_CN.md +551 -143
  5. package/SPECIFICATION.md +20 -14
  6. package/SPECIFICATION.zh-CN.md +20 -14
  7. package/dist/cjs/binary-tree.cjs +6460 -1591
  8. package/dist/cjs/graph.cjs +440 -20
  9. package/dist/cjs/hash.cjs +125 -22
  10. package/dist/cjs/heap.cjs +196 -47
  11. package/dist/cjs/index.cjs +8486 -2429
  12. package/dist/cjs/linked-list.cjs +456 -31
  13. package/dist/cjs/matrix.cjs +79 -9
  14. package/dist/cjs/priority-queue.cjs +193 -44
  15. package/dist/cjs/queue.cjs +391 -2
  16. package/dist/cjs/stack.cjs +92 -6
  17. package/dist/cjs/trie.cjs +122 -28
  18. package/dist/cjs-legacy/binary-tree.cjs +6484 -1612
  19. package/dist/cjs-legacy/graph.cjs +440 -20
  20. package/dist/cjs-legacy/hash.cjs +125 -22
  21. package/dist/cjs-legacy/heap.cjs +196 -47
  22. package/dist/cjs-legacy/index.cjs +8654 -2594
  23. package/dist/cjs-legacy/linked-list.cjs +456 -31
  24. package/dist/cjs-legacy/matrix.cjs +79 -9
  25. package/dist/cjs-legacy/priority-queue.cjs +193 -44
  26. package/dist/cjs-legacy/queue.cjs +391 -2
  27. package/dist/cjs-legacy/stack.cjs +92 -6
  28. package/dist/cjs-legacy/trie.cjs +122 -28
  29. package/dist/esm/binary-tree.mjs +6460 -1591
  30. package/dist/esm/graph.mjs +440 -20
  31. package/dist/esm/hash.mjs +125 -22
  32. package/dist/esm/heap.mjs +196 -47
  33. package/dist/esm/index.mjs +8486 -2430
  34. package/dist/esm/linked-list.mjs +456 -31
  35. package/dist/esm/matrix.mjs +79 -9
  36. package/dist/esm/priority-queue.mjs +193 -44
  37. package/dist/esm/queue.mjs +391 -2
  38. package/dist/esm/stack.mjs +92 -6
  39. package/dist/esm/trie.mjs +122 -28
  40. package/dist/esm-legacy/binary-tree.mjs +6484 -1612
  41. package/dist/esm-legacy/graph.mjs +440 -20
  42. package/dist/esm-legacy/hash.mjs +125 -22
  43. package/dist/esm-legacy/heap.mjs +196 -47
  44. package/dist/esm-legacy/index.mjs +8654 -2595
  45. package/dist/esm-legacy/linked-list.mjs +456 -31
  46. package/dist/esm-legacy/matrix.mjs +79 -9
  47. package/dist/esm-legacy/priority-queue.mjs +193 -44
  48. package/dist/esm-legacy/queue.mjs +391 -2
  49. package/dist/esm-legacy/stack.mjs +92 -6
  50. package/dist/esm-legacy/trie.mjs +122 -28
  51. package/dist/types/common/error.d.ts +9 -0
  52. package/dist/types/common/index.d.ts +1 -1
  53. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +98 -2
  54. package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +112 -0
  55. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +214 -13
  56. package/dist/types/data-structures/binary-tree/bst.d.ts +294 -3
  57. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +155 -8
  58. package/dist/types/data-structures/binary-tree/segment-tree.d.ts +48 -0
  59. package/dist/types/data-structures/binary-tree/tree-map.d.ts +1370 -323
  60. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1329 -316
  61. package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +1116 -295
  62. package/dist/types/data-structures/binary-tree/tree-set.d.ts +1330 -326
  63. package/dist/types/data-structures/graph/directed-graph.d.ts +80 -0
  64. package/dist/types/data-structures/graph/undirected-graph.d.ts +72 -0
  65. package/dist/types/data-structures/hash/hash-map.d.ts +95 -6
  66. package/dist/types/data-structures/heap/heap.d.ts +154 -12
  67. package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +143 -0
  68. package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +121 -1
  69. package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +144 -0
  70. package/dist/types/data-structures/matrix/matrix.d.ts +64 -0
  71. package/dist/types/data-structures/queue/deque.d.ts +142 -0
  72. package/dist/types/data-structures/queue/queue.d.ts +109 -0
  73. package/dist/types/data-structures/stack/stack.d.ts +82 -2
  74. package/dist/types/data-structures/trie/trie.d.ts +96 -0
  75. package/dist/types/interfaces/binary-tree.d.ts +2 -3
  76. package/dist/types/types/data-structures/binary-tree/bst.d.ts +1 -0
  77. package/dist/types/types/data-structures/binary-tree/tree-map.d.ts +5 -0
  78. package/dist/types/types/data-structures/binary-tree/tree-multi-set.d.ts +4 -0
  79. package/dist/types/types/data-structures/binary-tree/tree-set.d.ts +4 -0
  80. package/dist/umd/data-structure-typed.js +8623 -2564
  81. package/dist/umd/data-structure-typed.min.js +5 -5
  82. package/docs-site-docusaurus/docs/api/classes/AVLTree.md +696 -194
  83. package/docs-site-docusaurus/docs/api/classes/AVLTreeNode.md +11 -11
  84. package/docs-site-docusaurus/docs/api/classes/AbstractGraph.md +71 -71
  85. package/docs-site-docusaurus/docs/api/classes/BST.md +639 -189
  86. package/docs-site-docusaurus/docs/api/classes/BSTNode.md +13 -13
  87. package/docs-site-docusaurus/docs/api/classes/BinaryIndexedTree.md +15 -15
  88. package/docs-site-docusaurus/docs/api/classes/BinaryTree.md +148 -160
  89. package/docs-site-docusaurus/docs/api/classes/BinaryTreeNode.md +13 -13
  90. package/docs-site-docusaurus/docs/api/classes/Deque.md +105 -91
  91. package/docs-site-docusaurus/docs/api/classes/DirectedGraph.md +82 -82
  92. package/docs-site-docusaurus/docs/api/classes/DoublyLinkedList.md +104 -74
  93. package/docs-site-docusaurus/docs/api/classes/DoublyLinkedListNode.md +8 -8
  94. package/docs-site-docusaurus/docs/api/classes/FibonacciHeap.md +12 -12
  95. package/docs-site-docusaurus/docs/api/classes/FibonacciHeapNode.md +1 -1
  96. package/docs-site-docusaurus/docs/api/classes/HashMap.md +51 -51
  97. package/docs-site-docusaurus/docs/api/classes/Heap.md +96 -85
  98. package/docs-site-docusaurus/docs/api/classes/IterableElementBase.md +25 -25
  99. package/docs-site-docusaurus/docs/api/classes/IterableEntryBase.md +33 -33
  100. package/docs-site-docusaurus/docs/api/classes/LinearBase.md +50 -50
  101. package/docs-site-docusaurus/docs/api/classes/LinearLinkedBase.md +55 -55
  102. package/docs-site-docusaurus/docs/api/classes/LinkedHashMap.md +55 -55
  103. package/docs-site-docusaurus/docs/api/classes/LinkedListNode.md +6 -6
  104. package/docs-site-docusaurus/docs/api/classes/LinkedListQueue.md +78 -78
  105. package/docs-site-docusaurus/docs/api/classes/MapGraph.md +82 -82
  106. package/docs-site-docusaurus/docs/api/classes/Matrix.md +31 -31
  107. package/docs-site-docusaurus/docs/api/classes/MaxHeap.md +104 -89
  108. package/docs-site-docusaurus/docs/api/classes/MaxPriorityQueue.md +104 -89
  109. package/docs-site-docusaurus/docs/api/classes/MinHeap.md +104 -89
  110. package/docs-site-docusaurus/docs/api/classes/MinPriorityQueue.md +104 -89
  111. package/docs-site-docusaurus/docs/api/classes/Navigator.md +5 -5
  112. package/docs-site-docusaurus/docs/api/classes/PriorityQueue.md +103 -88
  113. package/docs-site-docusaurus/docs/api/classes/Queue.md +112 -60
  114. package/docs-site-docusaurus/docs/api/classes/RedBlackTree.md +708 -206
  115. package/docs-site-docusaurus/docs/api/classes/SegmentTree.md +10 -10
  116. package/docs-site-docusaurus/docs/api/classes/SinglyLinkedList.md +79 -79
  117. package/docs-site-docusaurus/docs/api/classes/SinglyLinkedListNode.md +6 -6
  118. package/docs-site-docusaurus/docs/api/classes/SkipList.md +44 -44
  119. package/docs-site-docusaurus/docs/api/classes/Stack.md +42 -42
  120. package/docs-site-docusaurus/docs/api/classes/TreeMap.md +236 -33
  121. package/docs-site-docusaurus/docs/api/classes/TreeMultiMap.md +162 -46
  122. package/docs-site-docusaurus/docs/api/classes/TreeSet.md +232 -32
  123. package/docs-site-docusaurus/docs/api/classes/Trie.md +47 -47
  124. package/docs-site-docusaurus/docs/api/classes/TrieNode.md +8 -8
  125. package/docs-site-docusaurus/docs/api/classes/UndirectedGraph.md +81 -81
  126. package/docs-site-docusaurus/docs/guide/architecture.md +75 -5
  127. package/docs-site-docusaurus/docs/guide/concepts.md +53 -3
  128. package/docs-site-docusaurus/docs/guide/faq.md +233 -0
  129. package/docs-site-docusaurus/docs/guide/guides.md +43 -58
  130. package/docs-site-docusaurus/docs/guide/installation.md +2 -0
  131. package/docs-site-docusaurus/docs/guide/integrations.md +75 -176
  132. package/docs-site-docusaurus/docs/guide/overview.md +132 -11
  133. package/docs-site-docusaurus/docs/guide/performance.md +2 -0
  134. package/docs-site-docusaurus/docs/guide/quick-start.md +31 -0
  135. package/docs-site-docusaurus/docs/guide/use-cases/_category_.json +6 -0
  136. package/docs-site-docusaurus/docs/guide/use-cases/array-sort-alternative.md +158 -0
  137. package/docs-site-docusaurus/docs/guide/use-cases/heap-vs-sorting.md +92 -0
  138. package/docs-site-docusaurus/docs/guide/use-cases/map-vs-treemap.md +151 -0
  139. package/docs-site-docusaurus/docs/guide/use-cases/priority-queue-typescript.md +113 -0
  140. package/docs-site-docusaurus/docs/guide/use-cases/treemap-javascript.md +151 -0
  141. package/docs-site-docusaurus/docusaurus.config.ts +1 -1
  142. package/docs-site-docusaurus/src/pages/index.tsx +55 -2
  143. package/docs-site-docusaurus/static/llms.txt +37 -0
  144. package/docs-site-docusaurus/typedoc.json +1 -0
  145. package/llms.txt +37 -0
  146. package/package.json +65 -56
  147. package/src/common/error.ts +19 -1
  148. package/src/common/index.ts +1 -1
  149. package/src/data-structures/base/iterable-element-base.ts +3 -2
  150. package/src/data-structures/binary-tree/avl-tree.ts +99 -5
  151. package/src/data-structures/binary-tree/binary-indexed-tree.ts +102 -4
  152. package/src/data-structures/binary-tree/binary-tree.ts +239 -78
  153. package/src/data-structures/binary-tree/bst.ts +542 -13
  154. package/src/data-structures/binary-tree/red-black-tree.ts +155 -15
  155. package/src/data-structures/binary-tree/segment-tree.ts +42 -0
  156. package/src/data-structures/binary-tree/tree-map.ts +1223 -261
  157. package/src/data-structures/binary-tree/tree-multi-map.ts +939 -30
  158. package/src/data-structures/binary-tree/tree-multi-set.ts +746 -10
  159. package/src/data-structures/binary-tree/tree-set.ts +1018 -99
  160. package/src/data-structures/graph/abstract-graph.ts +2 -2
  161. package/src/data-structures/graph/directed-graph.ts +71 -1
  162. package/src/data-structures/graph/undirected-graph.ts +64 -1
  163. package/src/data-structures/hash/hash-map.ts +102 -16
  164. package/src/data-structures/heap/heap.ts +153 -23
  165. package/src/data-structures/heap/max-heap.ts +2 -2
  166. package/src/data-structures/linked-list/doubly-linked-list.ts +139 -0
  167. package/src/data-structures/linked-list/singly-linked-list.ts +106 -1
  168. package/src/data-structures/linked-list/skip-linked-list.ts +131 -5
  169. package/src/data-structures/matrix/matrix.ts +65 -9
  170. package/src/data-structures/priority-queue/max-priority-queue.ts +2 -2
  171. package/src/data-structures/queue/deque.ts +130 -0
  172. package/src/data-structures/queue/queue.ts +109 -0
  173. package/src/data-structures/stack/stack.ts +75 -5
  174. package/src/data-structures/trie/trie.ts +86 -2
  175. package/src/interfaces/binary-tree.ts +1 -9
  176. package/src/types/data-structures/binary-tree/bst.ts +1 -0
  177. package/src/types/data-structures/binary-tree/tree-map.ts +6 -0
  178. package/src/types/data-structures/binary-tree/tree-multi-set.ts +5 -0
  179. package/src/types/data-structures/binary-tree/tree-set.ts +5 -0
  180. package/.vitepress/cache/deps_temp_51f5f1b0/chunk-7OIKW5WK.js +0 -12984
  181. package/.vitepress/cache/deps_temp_51f5f1b0/package.json +0 -3
  182. package/.vitepress/cache/deps_temp_51f5f1b0/vitepress___@vue_devtools-api.js +0 -4505
  183. package/.vitepress/cache/deps_temp_51f5f1b0/vitepress___@vueuse_core.js +0 -9731
  184. package/.vitepress/cache/deps_temp_51f5f1b0/vue.js +0 -347
@@ -1,13 +1,14 @@
1
1
  ---
2
2
  sidebar_label: "INTEGRATIONS"
3
3
  description: "Integrate data-structure-typed with React, Express, NestJS, and other frameworks. Production-ready patterns."
4
+ title: "Framework Integrations — React, Express, NestJS"
5
+ keywords: ["data-structure-typed react", "typescript data structures express", "nestjs data structures", "production patterns"]
4
6
  ---
5
-
6
7
  # INTEGRATIONS
7
8
 
8
9
  How to use data-structure-typed with React, Express, Nest.js, and other frameworks.
9
10
 
10
- **[Back to README](/.md) • [Code Examples](/guide/guides.md) • [Performance](/guide/performance.md)**
11
+ **[Back to README](/docs/guide/quick-start) • [Code Examples](/guide/guides.md) • [Performance](/guide/performance.md)**
11
12
 
12
13
  ---
13
14
 
@@ -289,6 +290,8 @@ app.get('/api/data', (req, res) => {
289
290
 
290
291
  ### Use Case: Product Price Index Service
291
292
 
293
+ > Full working demo: [StackBlitz NestJS Playground](https://stackblitz.com/github/zrwusa/dst-playgrounds/tree/main/apps/nestjs?file=src%2Fproduct%2Fservices%2Fproduct-price-index.service.ts&title=data-structure-typed%20%E2%80%94%20NestJS%20Product%20API)
294
+
292
295
  ```typescript
293
296
  import {
294
297
  BadRequestException,
@@ -307,7 +310,6 @@ export interface Product {
307
310
  lastUpdated?: Date;
308
311
  }
309
312
 
310
- /** KEY INSIGHT: Use compound keys to solve the problem of "multiple products at the same price" */
311
313
  interface CompositeKey {
312
314
  price: number;
313
315
  productId: string;
@@ -326,13 +328,8 @@ export type TierName = 'budget' | 'mid-range' | 'premium';
326
328
  * Point Lookup | O(1) | O(1) | O(1)
327
329
  * Insert/Update | O(log n) | O(n) | O(log n)
328
330
  * Sort by Price | O(n) | O(n log n)| O(n log n)
329
- * Multiple at Price | Supported | | Complex
330
- *
331
- * Advantages:
332
- * - O(1) idToKeyMap lookup + O(log n) tree operations
333
- * - Automatic ordering without post-sort
334
- * - Efficient range queries for pricing tiers
335
- * - Low memory footprint vs duplicate maps
331
+ * Pagination | O(log n + k) | O(n log n)| O(n log n)
332
+ * Rank/Percentile | O(log n) | O(n) | O(n log n)
336
333
  */
337
334
  @Injectable()
338
335
  export class ProductPriceIndexService {
@@ -346,228 +343,130 @@ export class ProductPriceIndexService {
346
343
  if (priceCmp !== 0) return priceCmp;
347
344
  return a.productId.localeCompare(b.productId);
348
345
  },
346
+ enableOrderStatistic: true, // Enables getRank/getByRank/rangeByRank
349
347
  });
350
348
  this.idToKeyMap = new Map();
351
349
  }
352
350
 
353
- /** Time Complexity: O(log n) */
351
+ /** O(log n) */
354
352
  addProduct(product: Product): Product {
355
353
  if (this.idToKeyMap.has(product.id))
356
354
  throw new BadRequestException(`Product ${product.id} already exists`);
357
355
 
358
356
  product.lastUpdated = new Date();
359
-
360
- const key: CompositeKey = {
361
- price: product.price,
362
- productId: product.id,
363
- };
364
-
365
- this.priceIndex.add(key, product);
357
+ const key: CompositeKey = { price: product.price, productId: product.id };
358
+ this.priceIndex.set(key, product);
366
359
  this.idToKeyMap.set(product.id, key);
367
-
368
360
  return product;
369
361
  }
370
362
 
371
- /** Time Complexity: O(log n) */
372
- updateProduct(productId: string, updates: Partial<Product>): Product {
373
- const oldKey = this.idToKeyMap.get(productId);
374
- if (oldKey === undefined)
375
- throw new NotFoundException(`Product ${productId} not found`);
376
-
377
- const existing = this.priceIndex.get(oldKey);
378
- if (!existing)
379
- throw new NotFoundException(`Product ${productId} not found`);
380
-
381
- const updated: Product = {
382
- ...existing,
383
- ...updates,
384
- id: existing.id,
385
- lastUpdated: new Date(),
386
- };
387
-
388
- const newPrice = updates.price ?? existing.price;
389
-
390
- this.priceIndex.delete(oldKey);
391
- const currentKey: CompositeKey = {
392
- price: newPrice,
393
- productId,
394
- };
395
- this.priceIndex.set(currentKey, updated);
396
- this.idToKeyMap.set(productId, currentKey);
397
-
398
- return updated;
399
- }
400
-
401
- /** Time Complexity: O(1) */
363
+ /** O(1) — HashMap lookup */
402
364
  getProductById(productId: string): Product {
403
365
  const key = this.idToKeyMap.get(productId);
404
-
405
366
  if (key === undefined)
406
367
  throw new NotFoundException(`Product ${productId} not found`);
407
-
408
368
  return this.priceIndex.get(key)!;
409
369
  }
410
370
 
411
- /** Time Complexity: O(log n + k) */
371
+ /** O(log n + k) — directly returns values, no secondary lookup */
412
372
  getProductsByPriceRange(minPrice: number, maxPrice: number): Product[] {
413
373
  const range = new Range(
414
374
  { price: minPrice, productId: '' },
415
375
  { price: maxPrice, productId: '\uffff' },
416
- true, // includeLow
417
- true, // includeHigh
376
+ true,
377
+ true,
418
378
  );
419
-
420
- const keys = this.priceIndex.rangeSearch(range, (n) => n.key);
421
- return keys.map((key) => this.priceIndex.get(key)!);
379
+ return this.priceIndex.rangeSearch(range, (n) => n.value!);
422
380
  }
423
381
 
424
- /** Time Complexity: O(log n) */
382
+ /** O(log n) — NavigableMap floor() */
425
383
  getHighestPricedProductWithinBudget(maxBudget: number): Product | null {
426
- const key: CompositeKey = {
427
- price: maxBudget,
428
- productId: '\uffff',
429
- };
384
+ const key: CompositeKey = { price: maxBudget, productId: '\uffff' };
430
385
  const floorKey = this.priceIndex.floor(key);
431
386
  return floorKey ? this.priceIndex.get(floorKey)! : null;
432
387
  }
433
388
 
434
- /** Time O(log n) */
435
- getCheapestProductAbovePrice(minPrice: number): Product | null {
436
- const key: CompositeKey = {
437
- price: minPrice,
438
- productId: '\uffff',
439
- };
440
- const higherKey = this.priceIndex.higher(key);
441
- return higherKey ? this.priceIndex.get(higherKey)! : null;
442
- }
443
-
444
- /** Time Complexity: O(log n + k) */
445
- getProductsByTier(tierName: TierName): Product[] {
446
- const tiers = {
447
- budget: [0, 50],
448
- 'mid-range': [50, 200],
449
- premium: [200, Infinity],
450
- };
451
-
452
- const [min, max] = tiers[tierName];
453
- return this.getProductsByPriceRange(min, max);
454
- }
455
-
456
- /** Time Complexity: O(log n + k + m) */
457
- getProductsByPriceAndCategory(
458
- minPrice: number,
459
- maxPrice: number,
460
- category: string,
461
- ): Product[] {
462
- const priceRangeProducts = this.getProductsByPriceRange(minPrice, maxPrice);
463
- return priceRangeProducts.filter(
464
- (p) => p.category.toLowerCase() === category.toLowerCase(),
465
- );
466
- }
467
-
468
- /** Time Complexity: O((log n + k) * log n) */
469
- applyDiscountToRange(
470
- minPrice: number,
471
- maxPrice: number,
472
- discountPercent: number,
473
- ): Product[] {
474
- const products = this.getProductsByPriceRange(minPrice, maxPrice);
475
- const updated: Product[] = [];
476
-
477
- for (const product of products) {
478
- const newPrice = product.price * (1 - discountPercent / 100);
479
- const updatedProduct = this.updateProduct(product.id, {
480
- price: newPrice,
481
- });
482
- updated.push(updatedProduct);
483
- }
484
-
485
- return updated;
389
+ /** O(n) — iterator protocol, one-liner */
390
+ getAllProductsSortedByPrice(): Product[] {
391
+ return [...this.priceIndex.values()];
486
392
  }
487
393
 
488
- /** Time Complexity: O(log n) */
489
- deleteProduct(productId: string): void {
490
- const key = this.idToKeyMap.get(productId);
491
-
492
- if (key === undefined)
493
- throw new NotFoundException(`Product ${productId} not found`);
494
-
495
- this.priceIndex.delete(key);
496
- this.idToKeyMap.delete(productId);
497
- }
394
+ /**
395
+ * O(n) for totalValue, O(log n) for min/max
396
+ * min/max use getLeftMost/getRightMost instead of full traversal
397
+ */
398
+ getStatistics() {
399
+ if (this.idToKeyMap.size === 0)
400
+ return { totalProducts: 0, priceRange: { min: 0, max: 0 }, averagePrice: 0, totalValue: 0 };
498
401
 
499
- /** Time Complexity: O(n) */
500
- getStatistics(): {
501
- totalProducts: number;
502
- priceRange: { min: number; max: number };
503
- averagePrice: number;
504
- totalValue: number;
505
- } {
506
- if (this.idToKeyMap.size === 0) {
507
- return {
508
- totalProducts: 0,
509
- priceRange: { min: 0, max: 0 },
510
- averagePrice: 0,
511
- totalValue: 0,
512
- };
513
- }
402
+ const minKey = this.priceIndex.getLeftMost();
403
+ const maxKey = this.priceIndex.getRightMost();
514
404
 
515
- let minPrice = Infinity;
516
- let maxPrice = -Infinity;
517
405
  let totalValue = 0;
518
406
  let totalProducts = 0;
519
-
520
- let entry = this.priceIndex.getLeftMost((node) => node);
521
-
522
- while (entry) {
523
- const product = this.priceIndex.get(entry.key);
524
- if (product) {
525
- minPrice = Math.min(minPrice, product.price);
526
- maxPrice = Math.max(maxPrice, product.price);
527
- totalValue += product.price * product.quantity;
528
- totalProducts += product.quantity;
529
- }
530
-
531
- entry = this.priceIndex.higher(entry.key, (node) => node);
407
+ for (const [, product] of this.priceIndex) {
408
+ totalValue += product.price * product.quantity;
409
+ totalProducts += product.quantity;
532
410
  }
533
411
 
534
412
  return {
535
- totalProducts: totalProducts,
536
- priceRange: { min: minPrice, max: maxPrice },
413
+ totalProducts,
414
+ priceRange: { min: minKey?.price ?? 0, max: maxKey?.price ?? 0 },
537
415
  averagePrice: totalValue / totalProducts,
538
416
  totalValue,
539
417
  };
540
418
  }
541
419
 
542
- /** Time Complexity: O(n) */
543
- getAllProductsSortedByPrice(): Product[] {
544
- const products: Product[] = [];
545
- let curNode = this.priceIndex.getLeftMost((node) => node);
420
+ // ── Order-Statistic API (rank-based queries) ──────────────────────
546
421
 
547
- while (curNode) {
548
- if (curNode.key) products.push(this.priceIndex.get(curNode.key)!);
549
- curNode = this.priceIndex.higher(curNode.key, (node) => node);
550
- }
422
+ /** O(log n + pageSize) — rank-based pagination */
423
+ getProductsByPage(page: number, pageSize: number): Product[] {
424
+ const start = page * pageSize;
425
+ const end = Math.min(start + pageSize - 1, this.priceIndex.size - 1);
426
+ if (start >= this.priceIndex.size) return [];
427
+ const keys = this.priceIndex.rangeByRank(start, end);
428
+ return keys.map((key) => this.priceIndex.get(key)!);
429
+ }
551
430
 
552
- return products;
431
+ /** O(log n) — what % of products are cheaper */
432
+ getPricePercentile(productId: string): number {
433
+ const key = this.idToKeyMap.get(productId);
434
+ if (!key) throw new NotFoundException(`Product ${productId} not found`);
435
+ return (this.priceIndex.getRank(key) / this.priceIndex.size) * 100;
553
436
  }
554
437
 
555
- /** O(1) */
556
- getProductCount(): number {
557
- return this.idToKeyMap.size;
438
+ /** O(log n) — median product */
439
+ getMedianProduct(): Product | null {
440
+ if (this.priceIndex.size === 0) return null;
441
+ const key = this.priceIndex.getByRank(Math.floor((this.priceIndex.size - 1) / 2));
442
+ return key ? this.priceIndex.get(key)! : null;
558
443
  }
559
444
 
560
- /** O(1) */
561
- hasProduct(productId: string): boolean {
562
- return this.idToKeyMap.has(productId);
445
+ /** O(log n + k) — top N cheapest */
446
+ getTopNCheapest(n: number): Product[] {
447
+ const end = Math.min(n - 1, this.priceIndex.size - 1);
448
+ if (end < 0) return [];
449
+ return this.priceIndex.rangeByRank(0, end).map((key) => this.priceIndex.get(key)!);
563
450
  }
564
451
 
565
- /** O(n) */
566
- getAllProductIds(): string[] {
567
- return [...this.idToKeyMap.keys()];
452
+ /** O(log n + k) — top N most expensive */
453
+ getTopNExpensive(n: number): Product[] {
454
+ const size = this.priceIndex.size;
455
+ if (size === 0) return [];
456
+ const start = Math.max(size - n, 0);
457
+ return this.priceIndex.rangeByRank(start, size - 1)
458
+ .map((key) => this.priceIndex.get(key)!)
459
+ .reverse();
568
460
  }
569
- }
570
461
 
462
+ /** O(log n) — dynamic tier by percentile, no hardcoded price ranges */
463
+ getTierByPercentile(productId: string): TierName {
464
+ const pct = this.getPricePercentile(productId);
465
+ if (pct < 33) return 'budget';
466
+ if (pct < 66) return 'mid-range';
467
+ return 'premium';
468
+ }
469
+ }
571
470
  ```
572
471
 
573
472
  ### Use Case: Task Queue Controller
@@ -1,13 +1,14 @@
1
1
  ---
2
2
  sidebar_label: "OVERVIEW"
3
3
  description: "Complete overview of all 20+ data structures: trees, heaps, graphs, queues, linked lists, hash maps, and more."
4
+ title: "Data Structures Overview — Trees, Heaps, Graphs, Queues"
5
+ keywords: ["typescript data structures overview", "red black tree", "heap", "priority queue", "trie", "graph", "deque", "treemap", "treeset"]
4
6
  ---
5
-
6
7
  # OVERVIEW
7
8
 
8
9
  A quick-reference guide to all structures, common operations, and usage patterns. For complete API details with method signatures and examples, see the **[Full API Docs](https://data-structure-typed-docs.vercel.app/)**.
9
10
 
10
- **[Back to README](/.md) • [API Docs](https://data-structure-typed-docs.vercel.app/) • [Real-World Examples](/guide/guides.md) • [Performance](/guide/performance.md)**
11
+ **[Back to README](/docs/guide/quick-start) • [API Docs](https://data-structure-typed-docs.vercel.app/) • [Real-World Examples](/guide/guides.md) • [Performance](/guide/performance.md)**
11
12
 
12
13
  ---
13
14
 
@@ -55,7 +56,7 @@ A quick-reference guide to all structures, common operations, and usage patterns
55
56
  import { Stack } from 'data-structure-typed';
56
57
 
57
58
  const stack = new Stack<number>([1, 2]);
58
- stack.push(3); // add to bottom
59
+ stack.push(3); // add to top
59
60
  const top = stack.pop(); // Remove from top - O(1)
60
61
  const peek = stack.peek(); // View top
61
62
  stack.print(); // [1, 2]
@@ -166,6 +167,97 @@ avl.print()
166
167
  // 4 9
167
168
  ```
168
169
 
170
+ #### TreeMap (Ordered Map)
171
+
172
+ ```typescript
173
+ import { TreeMap } from 'data-structure-typed';
174
+
175
+ const tm = new TreeMap<number, string>([[3, 'c'], [1, 'a'], [2, 'b']]);
176
+ tm.set(4, 'd'); // Set key-value - O(log n)
177
+ tm.get(2); // 'b' - O(log n)
178
+ tm.has(3); // true
179
+ tm.delete(1); // Remove - O(log n)
180
+
181
+ // Navigation — Java NavigableMap-style
182
+ tm.first(); // [2, 'b'] — smallest entry
183
+ tm.last(); // [4, 'd'] — largest entry
184
+ tm.ceiling(3); // [3, 'c'] — smallest >= 3
185
+ tm.floor(2); // [2, 'b'] — largest <= 2
186
+ tm.higher(2); // [3, 'c'] — strictly > 2
187
+ tm.lower(3); // [2, 'b'] — strictly < 3
188
+
189
+ // Iteration (sorted order)
190
+ console.log([...tm.keys()]); // [2, 3, 4]
191
+ console.log([...tm.values()]); // ['b', 'c', 'd']
192
+
193
+ // Bulk operations
194
+ tm.setMany([[5, 'e'], [6, 'f']]); // Set multiple at once
195
+
196
+ // Functional
197
+ const filtered = tm.filter((v, k) => k > 2);
198
+ const mapped = tm.map((v, k) => [k * 10, v!.toUpperCase()] as [number, string]);
199
+ ```
200
+
201
+ #### TreeSet (Ordered Set)
202
+
203
+ ```typescript
204
+ import { TreeSet } from 'data-structure-typed';
205
+
206
+ const ts = new TreeSet<number>([5, 3, 8, 1]);
207
+ ts.add(4); // Add - O(log n)
208
+ ts.has(3); // true
209
+ ts.delete(5); // Remove - O(log n)
210
+
211
+ // Navigation
212
+ ts.first(); // 1
213
+ ts.last(); // 8
214
+ ts.ceiling(4); // 4 — smallest >= 4
215
+ ts.floor(6); // 4 — largest <= 6
216
+ ts.higher(3); // 4 — strictly > 3
217
+ ts.lower(4); // 3 — strictly < 4
218
+
219
+ // Iteration (sorted order)
220
+ console.log([...ts.keys()]); // [1, 3, 4, 8]
221
+
222
+ // Bulk operations
223
+ ts.addMany([10, 20, 30]); // Add multiple at once
224
+ ```
225
+
226
+ #### Order-Statistic Tree (Rank Queries)
227
+
228
+ Enable `enableOrderStatistic: true` on any tree-based structure to get O(log n) rank operations:
229
+
230
+ ```typescript
231
+ import { RedBlackTree, TreeMap, TreeSet } from 'data-structure-typed';
232
+
233
+ // Works with RedBlackTree, TreeMap, TreeSet, TreeMultiMap, TreeMultiSet
234
+ const tree = new RedBlackTree<number, string>(
235
+ [[100, 'Alice'], [85, 'Bob'], [92, 'Charlie'], [78, 'Diana']],
236
+ { comparator: (a, b) => b - a, enableOrderStatistic: true }
237
+ );
238
+
239
+ // getByRank(k) — element at position k in tree order, O(log n)
240
+ tree.getByRank(0); // 100 (1st in tree order)
241
+ tree.getByRank(2); // 92 (3rd in tree order)
242
+
243
+ // getRank(key) — count of elements before key in tree order, O(log n)
244
+ tree.getRank(92); // 2
245
+
246
+ // rangeByRank(start, end) — elements between positions, O(log n + k)
247
+ tree.rangeByRank(0, 2); // [100, 92, 85] — positions 0..2
248
+
249
+ // Also works with wrapper classes
250
+ const tm = new TreeMap<number, string>([], { enableOrderStatistic: true });
251
+ tm.set(10, 'a'); tm.set(20, 'b'); tm.set(30, 'c');
252
+ tm.getByRank(1); // [20, 'b']
253
+ tm.getRank(20); // 1
254
+
255
+ const ts = new TreeSet<number>([], { enableOrderStatistic: true });
256
+ ts.addMany([10, 20, 30]);
257
+ ts.getByRank(0); // 10
258
+ ts.getRank(30); // 2
259
+ ```
260
+
169
261
  ### Heap & Priority Queue
170
262
 
171
263
  #### Heap
@@ -184,7 +276,9 @@ const peek = minHeap.peek(); // View minimum - O(1)
184
276
  ```typescript
185
277
  import { MaxPriorityQueue } from 'data-structure-typed';
186
278
 
187
- const pq = new MaxPriorityQueue<Task>();
279
+ const pq = new MaxPriorityQueue<Task>([], {
280
+ comparator: (a, b) => b.priority - a.priority
281
+ });
188
282
  pq.add({ id: 1, priority: 5 }); // Add - O(log n)
189
283
  const task = pq.poll(); // Remove highest - O(log n)
190
284
  const size = pq.size; // Current size
@@ -266,7 +360,7 @@ heap.peek(); // Highest priority element
266
360
  heap.size; // Current size
267
361
 
268
362
  // Trie
269
- trie.getWords('hello'); // true
363
+ trie.has('hello'); // true
270
364
  trie.hasPrefix('hel'); // true
271
365
 
272
366
  // Graph
@@ -296,6 +390,12 @@ graph.deleteVertex('A'); // Remove vertex
296
390
  // All structures support:
297
391
  structure.clear(); // Remove all elements
298
392
  structure.delete(key); // Remove specific
393
+
394
+ // Conditional delete (BST-family and Deque)
395
+ tree.deleteWhere(node => node.key < 10); // Delete all matching
396
+ tree.deleteWhere(node => node.key < 10, true); // Delete first match only
397
+ tree.deleteWhere(new Range(5, 15)); // Delete by range
398
+ deque.deleteWhere((val, idx) => val > 100); // Deque predicate delete
299
399
  ```
300
400
 
301
401
  ---
@@ -328,12 +428,33 @@ structure.size; // Element count
328
428
  structure.isEmpty(); // Check empty
329
429
  ```
330
430
 
431
+ ### Raw Data Mapping
432
+
433
+ Pass raw objects directly — no `.map()` pre-processing needed:
434
+
435
+ ```typescript
436
+ // toElementFn — extract a field, store only that (Heap, Queue, Stack, LinkedList, Trie)
437
+ const heap = new MinHeap<number, User>(users, {
438
+ toElementFn: u => u.age
439
+ });
440
+
441
+ // toEntryFn — split into key-value pairs (TreeMap, HashMap, SkipList)
442
+ const map = new TreeMap<number, User, User>(users, {
443
+ toEntryFn: u => [u.id, u]
444
+ });
445
+
446
+ // comparator — store full objects, sort by a field (all sorted structures)
447
+ const set = new TreeSet<User>(users, {
448
+ comparator: (a, b) => a.id - b.id
449
+ });
450
+ ```
451
+
331
452
  ### Structure-Specific Methods
332
453
 
333
454
  #### Trees
334
455
 
335
456
  ```typescript
336
- tree.height; // Tree height
457
+ tree.height; // Tree height (getter)
337
458
  tree.isAVLBalanced(); // Balance check
338
459
  tree.getNode(key); // Get node object
339
460
  tree.getHeight(key); // Node height
@@ -344,10 +465,10 @@ tree.getRightMost(); // Rightmost node
344
465
  #### Deque
345
466
 
346
467
  ```typescript
347
- deque.peekFirst(); // View front
348
- deque.peekLast(); // View back
349
- deque.pollFirst(); // Remove front - O(1)
350
- deque.pollLast(); // Remove back - O(1)
468
+ deque.first; // View front (getter)
469
+ deque.last; // View back (getter)
470
+ deque.shift(); // Remove front - O(1)
471
+ deque.pop(); // Remove back - O(1)
351
472
  ```
352
473
 
353
474
  #### Graph
@@ -463,7 +584,7 @@ const sorted = [...new RedBlackTree(data).keys()]; // Instant sort!
463
584
 
464
585
  ---
465
586
 
466
- ## SkipList & SkipListSet
587
+ ## SkipList
467
588
 
468
589
  Probabilistic sorted containers. Interchangeable with `TreeMap`/`TreeSet`.
469
590
 
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  sidebar_label: "PERFORMANCE"
3
3
  description: "Benchmarks comparing data-structure-typed vs native Arrays, Maps, and C++ implementations. Includes methodology."
4
+ title: "Performance Benchmarks"
5
+ keywords: [typescript data structures performance, red black tree benchmark, heap benchmark, priority queue performance, javascript vs cpp]
4
6
  ---
5
7
 
6
8
  # PERFORMANCE
@@ -1,5 +1,7 @@
1
1
  ---
2
2
  description: "Get started with data-structure-typed in 30 seconds. Create trees, queues, and maps with a familiar JavaScript API."
3
+ title: "Quick Start — Get Running in 30 Seconds"
4
+ sidebar_label: "QUICK START"keywords: [data-structure-typed tutorial, typescript data structures getting started, treemap example, heap example]
3
5
  ---
4
6
 
5
7
  # Quick Start
@@ -32,6 +34,35 @@ leaderboard.set(95, 'Bob');
32
34
  const scores90to100 = leaderboard.rangeSearch([90, 100]);
33
35
  ```
34
36
 
37
+ ## Order-Statistic Tree (Rank Queries)
38
+
39
+ ```typescript
40
+ import { RedBlackTree } from 'data-structure-typed';
41
+
42
+ // Enable order-statistic for O(log n) rank operations
43
+ const tree = new RedBlackTree<number, string>([
44
+ [100, 'Alice'],
45
+ [85, 'Bob'],
46
+ [92, 'Charlie'],
47
+ [78, 'Diana'],
48
+ [95, 'Eve']
49
+ ], { comparator: (a, b) => b - a, enableOrderStatistic: true });
50
+
51
+ // select(k) — find k-th element (0-indexed)
52
+ console.log(tree.getByRank(0)); // 100 (1st in tree order)
53
+ console.log(tree.getByRank(2)); // 92 (3rd in tree order)
54
+
55
+ // rank(key) — how many elements before this key?
56
+ console.log(tree.getRank(92)); // 2 (2 elements before 92 in tree order)
57
+
58
+ // rangeByRank(start, end) — pagination
59
+ console.log(tree.rangeByRank(0, 2)); // [100, 95, 92] — top 3
60
+
61
+ // Inverse property: getByRank(getRank(key)) === key
62
+ const k = tree.getRank(85);
63
+ console.log(tree.getByRank(k)); // 85
64
+ ```
65
+
35
66
  ## Task Queue (Scheduling)
36
67
 
37
68
  ```typescript
@@ -0,0 +1,6 @@
1
+ {
2
+ "label": "Use Cases",
3
+ "position": 8,
4
+ "collapsible": true,
5
+ "collapsed": false
6
+ }