red-black-tree-typed 1.47.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 (341) hide show
  1. package/.eslintrc.js +61 -0
  2. package/.prettierignore +6 -0
  3. package/.prettierrc.js +16 -0
  4. package/LICENSE +21 -0
  5. package/README.md +713 -0
  6. package/coverage/clover.xml +13 -0
  7. package/coverage/coverage-final.json +96 -0
  8. package/coverage/coverage-summary.json +60 -0
  9. package/coverage/lcov-report/base.css +403 -0
  10. package/coverage/lcov-report/block-navigation.js +87 -0
  11. package/coverage/lcov-report/favicon.png +0 -0
  12. package/coverage/lcov-report/index.html +119 -0
  13. package/coverage/lcov-report/index.ts.html +109 -0
  14. package/coverage/lcov-report/prettify.css +1 -0
  15. package/coverage/lcov-report/prettify.js +2 -0
  16. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  17. package/coverage/lcov-report/sorter.js +206 -0
  18. package/coverage/lcov.info +14 -0
  19. package/dist/data-structures/binary-tree/avl-tree.d.ts +173 -0
  20. package/dist/data-structures/binary-tree/avl-tree.js +429 -0
  21. package/dist/data-structures/binary-tree/binary-indexed-tree.d.ts +149 -0
  22. package/dist/data-structures/binary-tree/binary-indexed-tree.js +269 -0
  23. package/dist/data-structures/binary-tree/binary-tree.d.ts +515 -0
  24. package/dist/data-structures/binary-tree/binary-tree.js +1665 -0
  25. package/dist/data-structures/binary-tree/bst.d.ts +253 -0
  26. package/dist/data-structures/binary-tree/bst.js +651 -0
  27. package/dist/data-structures/binary-tree/index.d.ts +7 -0
  28. package/dist/data-structures/binary-tree/index.js +23 -0
  29. package/dist/data-structures/binary-tree/rb-tree.d.ts +169 -0
  30. package/dist/data-structures/binary-tree/rb-tree.js +524 -0
  31. package/dist/data-structures/binary-tree/segment-tree.d.ts +67 -0
  32. package/dist/data-structures/binary-tree/segment-tree.js +180 -0
  33. package/dist/data-structures/binary-tree/tree-multimap.d.ts +162 -0
  34. package/dist/data-structures/binary-tree/tree-multimap.js +407 -0
  35. package/dist/data-structures/graph/abstract-graph.d.ts +450 -0
  36. package/dist/data-structures/graph/abstract-graph.js +1047 -0
  37. package/dist/data-structures/graph/directed-graph.d.ts +320 -0
  38. package/dist/data-structures/graph/directed-graph.js +530 -0
  39. package/dist/data-structures/graph/index.d.ts +4 -0
  40. package/dist/data-structures/graph/index.js +20 -0
  41. package/dist/data-structures/graph/map-graph.d.ts +73 -0
  42. package/dist/data-structures/graph/map-graph.js +93 -0
  43. package/dist/data-structures/graph/undirected-graph.d.ts +183 -0
  44. package/dist/data-structures/graph/undirected-graph.js +302 -0
  45. package/dist/data-structures/hash/hash-map.d.ts +186 -0
  46. package/dist/data-structures/hash/hash-map.js +367 -0
  47. package/dist/data-structures/hash/hash-table.d.ts +103 -0
  48. package/dist/data-structures/hash/hash-table.js +236 -0
  49. package/dist/data-structures/hash/index.d.ts +2 -0
  50. package/dist/data-structures/hash/index.js +18 -0
  51. package/dist/data-structures/heap/heap.d.ts +410 -0
  52. package/dist/data-structures/heap/heap.js +697 -0
  53. package/dist/data-structures/heap/index.d.ts +3 -0
  54. package/dist/data-structures/heap/index.js +19 -0
  55. package/dist/data-structures/heap/max-heap.d.ts +15 -0
  56. package/dist/data-structures/heap/max-heap.js +26 -0
  57. package/dist/data-structures/heap/min-heap.d.ts +15 -0
  58. package/dist/data-structures/heap/min-heap.js +26 -0
  59. package/dist/data-structures/index.d.ts +11 -0
  60. package/dist/data-structures/index.js +27 -0
  61. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +456 -0
  62. package/dist/data-structures/linked-list/doubly-linked-list.js +772 -0
  63. package/dist/data-structures/linked-list/index.d.ts +3 -0
  64. package/dist/data-structures/linked-list/index.js +19 -0
  65. package/dist/data-structures/linked-list/singly-linked-list.d.ts +414 -0
  66. package/dist/data-structures/linked-list/singly-linked-list.js +715 -0
  67. package/dist/data-structures/linked-list/skip-linked-list.d.ts +144 -0
  68. package/dist/data-structures/linked-list/skip-linked-list.js +251 -0
  69. package/dist/data-structures/matrix/index.d.ts +4 -0
  70. package/dist/data-structures/matrix/index.js +20 -0
  71. package/dist/data-structures/matrix/matrix.d.ts +21 -0
  72. package/dist/data-structures/matrix/matrix.js +28 -0
  73. package/dist/data-structures/matrix/matrix2d.d.ts +107 -0
  74. package/dist/data-structures/matrix/matrix2d.js +199 -0
  75. package/dist/data-structures/matrix/navigator.d.ts +52 -0
  76. package/dist/data-structures/matrix/navigator.js +106 -0
  77. package/dist/data-structures/matrix/vector2d.d.ts +200 -0
  78. package/dist/data-structures/matrix/vector2d.js +290 -0
  79. package/dist/data-structures/priority-queue/index.d.ts +3 -0
  80. package/dist/data-structures/priority-queue/index.js +19 -0
  81. package/dist/data-structures/priority-queue/max-priority-queue.d.ts +15 -0
  82. package/dist/data-structures/priority-queue/max-priority-queue.js +26 -0
  83. package/dist/data-structures/priority-queue/min-priority-queue.d.ts +15 -0
  84. package/dist/data-structures/priority-queue/min-priority-queue.js +26 -0
  85. package/dist/data-structures/priority-queue/priority-queue.d.ts +15 -0
  86. package/dist/data-structures/priority-queue/priority-queue.js +17 -0
  87. package/dist/data-structures/queue/deque.d.ts +572 -0
  88. package/dist/data-structures/queue/deque.js +990 -0
  89. package/dist/data-structures/queue/index.d.ts +2 -0
  90. package/dist/data-structures/queue/index.js +18 -0
  91. package/dist/data-structures/queue/queue.d.ts +209 -0
  92. package/dist/data-structures/queue/queue.js +274 -0
  93. package/dist/data-structures/stack/index.d.ts +1 -0
  94. package/dist/data-structures/stack/index.js +17 -0
  95. package/dist/data-structures/stack/stack.d.ts +106 -0
  96. package/dist/data-structures/stack/stack.js +136 -0
  97. package/dist/data-structures/tree/index.d.ts +1 -0
  98. package/dist/data-structures/tree/index.js +17 -0
  99. package/dist/data-structures/tree/tree.d.ts +8 -0
  100. package/dist/data-structures/tree/tree.js +40 -0
  101. package/dist/data-structures/trie/index.d.ts +1 -0
  102. package/dist/data-structures/trie/index.js +17 -0
  103. package/dist/data-structures/trie/trie.d.ts +155 -0
  104. package/dist/data-structures/trie/trie.js +326 -0
  105. package/dist/index.d.ts +10 -0
  106. package/dist/index.js +27 -0
  107. package/dist/interfaces/binary-tree.d.ts +7 -0
  108. package/dist/interfaces/binary-tree.js +2 -0
  109. package/dist/interfaces/doubly-linked-list.d.ts +1 -0
  110. package/dist/interfaces/doubly-linked-list.js +2 -0
  111. package/dist/interfaces/graph.d.ts +5 -0
  112. package/dist/interfaces/graph.js +2 -0
  113. package/dist/interfaces/heap.d.ts +1 -0
  114. package/dist/interfaces/heap.js +2 -0
  115. package/dist/interfaces/index.d.ts +8 -0
  116. package/dist/interfaces/index.js +24 -0
  117. package/dist/interfaces/navigator.d.ts +1 -0
  118. package/dist/interfaces/navigator.js +2 -0
  119. package/dist/interfaces/priority-queue.d.ts +1 -0
  120. package/dist/interfaces/priority-queue.js +2 -0
  121. package/dist/interfaces/segment-tree.d.ts +1 -0
  122. package/dist/interfaces/segment-tree.js +2 -0
  123. package/dist/interfaces/singly-linked-list.d.ts +1 -0
  124. package/dist/interfaces/singly-linked-list.js +2 -0
  125. package/dist/types/common.d.ts +20 -0
  126. package/dist/types/common.js +9 -0
  127. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +5 -0
  128. package/dist/types/data-structures/binary-tree/avl-tree.js +2 -0
  129. package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +1 -0
  130. package/dist/types/data-structures/binary-tree/binary-indexed-tree.js +2 -0
  131. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +31 -0
  132. package/dist/types/data-structures/binary-tree/binary-tree.js +24 -0
  133. package/dist/types/data-structures/binary-tree/bst.d.ts +8 -0
  134. package/dist/types/data-structures/binary-tree/bst.js +2 -0
  135. package/dist/types/data-structures/binary-tree/index.d.ts +6 -0
  136. package/dist/types/data-structures/binary-tree/index.js +22 -0
  137. package/dist/types/data-structures/binary-tree/rb-tree.d.ts +9 -0
  138. package/dist/types/data-structures/binary-tree/rb-tree.js +8 -0
  139. package/dist/types/data-structures/binary-tree/segment-tree.d.ts +1 -0
  140. package/dist/types/data-structures/binary-tree/segment-tree.js +2 -0
  141. package/dist/types/data-structures/binary-tree/tree-multimap.d.ts +5 -0
  142. package/dist/types/data-structures/binary-tree/tree-multimap.js +2 -0
  143. package/dist/types/data-structures/graph/abstract-graph.d.ts +10 -0
  144. package/dist/types/data-structures/graph/abstract-graph.js +2 -0
  145. package/dist/types/data-structures/graph/directed-graph.d.ts +1 -0
  146. package/dist/types/data-structures/graph/directed-graph.js +2 -0
  147. package/dist/types/data-structures/graph/index.d.ts +3 -0
  148. package/dist/types/data-structures/graph/index.js +19 -0
  149. package/dist/types/data-structures/graph/map-graph.d.ts +1 -0
  150. package/dist/types/data-structures/graph/map-graph.js +2 -0
  151. package/dist/types/data-structures/graph/undirected-graph.d.ts +1 -0
  152. package/dist/types/data-structures/graph/undirected-graph.js +2 -0
  153. package/dist/types/data-structures/hash/hash-map.d.ts +11 -0
  154. package/dist/types/data-structures/hash/hash-map.js +2 -0
  155. package/dist/types/data-structures/hash/hash-table.d.ts +1 -0
  156. package/dist/types/data-structures/hash/hash-table.js +2 -0
  157. package/dist/types/data-structures/hash/index.d.ts +3 -0
  158. package/dist/types/data-structures/hash/index.js +18 -0
  159. package/dist/types/data-structures/heap/heap.d.ts +1 -0
  160. package/dist/types/data-structures/heap/heap.js +2 -0
  161. package/dist/types/data-structures/heap/index.d.ts +1 -0
  162. package/dist/types/data-structures/heap/index.js +17 -0
  163. package/dist/types/data-structures/heap/max-heap.d.ts +1 -0
  164. package/dist/types/data-structures/heap/max-heap.js +2 -0
  165. package/dist/types/data-structures/heap/min-heap.d.ts +1 -0
  166. package/dist/types/data-structures/heap/min-heap.js +2 -0
  167. package/dist/types/data-structures/index.d.ts +11 -0
  168. package/dist/types/data-structures/index.js +27 -0
  169. package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +1 -0
  170. package/dist/types/data-structures/linked-list/doubly-linked-list.js +2 -0
  171. package/dist/types/data-structures/linked-list/index.d.ts +2 -0
  172. package/dist/types/data-structures/linked-list/index.js +18 -0
  173. package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +1 -0
  174. package/dist/types/data-structures/linked-list/singly-linked-list.js +2 -0
  175. package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +1 -0
  176. package/dist/types/data-structures/linked-list/skip-linked-list.js +2 -0
  177. package/dist/types/data-structures/matrix/index.d.ts +1 -0
  178. package/dist/types/data-structures/matrix/index.js +17 -0
  179. package/dist/types/data-structures/matrix/matrix.d.ts +1 -0
  180. package/dist/types/data-structures/matrix/matrix.js +2 -0
  181. package/dist/types/data-structures/matrix/matrix2d.d.ts +1 -0
  182. package/dist/types/data-structures/matrix/matrix2d.js +2 -0
  183. package/dist/types/data-structures/matrix/navigator.d.ts +14 -0
  184. package/dist/types/data-structures/matrix/navigator.js +2 -0
  185. package/dist/types/data-structures/matrix/vector2d.d.ts +1 -0
  186. package/dist/types/data-structures/matrix/vector2d.js +2 -0
  187. package/dist/types/data-structures/priority-queue/index.d.ts +3 -0
  188. package/dist/types/data-structures/priority-queue/index.js +19 -0
  189. package/dist/types/data-structures/priority-queue/max-priority-queue.d.ts +1 -0
  190. package/dist/types/data-structures/priority-queue/max-priority-queue.js +2 -0
  191. package/dist/types/data-structures/priority-queue/min-priority-queue.d.ts +1 -0
  192. package/dist/types/data-structures/priority-queue/min-priority-queue.js +2 -0
  193. package/dist/types/data-structures/priority-queue/priority-queue.d.ts +1 -0
  194. package/dist/types/data-structures/priority-queue/priority-queue.js +2 -0
  195. package/dist/types/data-structures/queue/deque.d.ts +1 -0
  196. package/dist/types/data-structures/queue/deque.js +2 -0
  197. package/dist/types/data-structures/queue/index.d.ts +2 -0
  198. package/dist/types/data-structures/queue/index.js +18 -0
  199. package/dist/types/data-structures/queue/queue.d.ts +1 -0
  200. package/dist/types/data-structures/queue/queue.js +2 -0
  201. package/dist/types/data-structures/stack/index.d.ts +1 -0
  202. package/dist/types/data-structures/stack/index.js +17 -0
  203. package/dist/types/data-structures/stack/stack.d.ts +1 -0
  204. package/dist/types/data-structures/stack/stack.js +2 -0
  205. package/dist/types/data-structures/tree/index.d.ts +1 -0
  206. package/dist/types/data-structures/tree/index.js +17 -0
  207. package/dist/types/data-structures/tree/tree.d.ts +1 -0
  208. package/dist/types/data-structures/tree/tree.js +2 -0
  209. package/dist/types/data-structures/trie/index.d.ts +1 -0
  210. package/dist/types/data-structures/trie/index.js +17 -0
  211. package/dist/types/data-structures/trie/trie.d.ts +1 -0
  212. package/dist/types/data-structures/trie/trie.js +2 -0
  213. package/dist/types/index.d.ts +3 -0
  214. package/dist/types/index.js +19 -0
  215. package/dist/types/utils/index.d.ts +2 -0
  216. package/dist/types/utils/index.js +18 -0
  217. package/dist/types/utils/utils.d.ts +7 -0
  218. package/dist/types/utils/utils.js +2 -0
  219. package/dist/types/utils/validate-type.d.ts +19 -0
  220. package/dist/types/utils/validate-type.js +2 -0
  221. package/dist/utils/index.d.ts +1 -0
  222. package/dist/utils/index.js +17 -0
  223. package/dist/utils/utils.d.ts +24 -0
  224. package/dist/utils/utils.js +89 -0
  225. package/docs/.nojekyll +1 -0
  226. package/docs/assets/highlight.css +92 -0
  227. package/docs/assets/main.js +59 -0
  228. package/docs/assets/navigation.js +1 -0
  229. package/docs/assets/search.js +1 -0
  230. package/docs/assets/style.css +1383 -0
  231. package/docs/classes/AVLTree.html +2046 -0
  232. package/docs/classes/AVLTreeNode.html +263 -0
  233. package/docs/index.html +523 -0
  234. package/docs/modules.html +45 -0
  235. package/jest.config.js +8 -0
  236. package/package.json +147 -0
  237. package/src/data-structures/binary-tree/avl-tree.ts +443 -0
  238. package/src/data-structures/binary-tree/binary-indexed-tree.ts +306 -0
  239. package/src/data-structures/binary-tree/binary-tree.ts +1974 -0
  240. package/src/data-structures/binary-tree/bst.ts +676 -0
  241. package/src/data-structures/binary-tree/index.ts +7 -0
  242. package/src/data-structures/binary-tree/rb-tree.ts +585 -0
  243. package/src/data-structures/binary-tree/segment-tree.ts +190 -0
  244. package/src/data-structures/binary-tree/tree-multimap.ts +435 -0
  245. package/src/data-structures/graph/abstract-graph.ts +1181 -0
  246. package/src/data-structures/graph/directed-graph.ts +593 -0
  247. package/src/data-structures/graph/index.ts +4 -0
  248. package/src/data-structures/graph/map-graph.ts +106 -0
  249. package/src/data-structures/graph/undirected-graph.ts +331 -0
  250. package/src/data-structures/hash/hash-map.ts +401 -0
  251. package/src/data-structures/hash/hash-table.ts +268 -0
  252. package/src/data-structures/hash/index.ts +2 -0
  253. package/src/data-structures/heap/heap.ts +790 -0
  254. package/src/data-structures/heap/index.ts +3 -0
  255. package/src/data-structures/heap/max-heap.ts +26 -0
  256. package/src/data-structures/heap/min-heap.ts +26 -0
  257. package/src/data-structures/index.ts +11 -0
  258. package/src/data-structures/linked-list/doubly-linked-list.ts +837 -0
  259. package/src/data-structures/linked-list/index.ts +3 -0
  260. package/src/data-structures/linked-list/singly-linked-list.ts +784 -0
  261. package/src/data-structures/linked-list/skip-linked-list.ts +295 -0
  262. package/src/data-structures/matrix/index.ts +4 -0
  263. package/src/data-structures/matrix/matrix.ts +27 -0
  264. package/src/data-structures/matrix/matrix2d.ts +211 -0
  265. package/src/data-structures/matrix/navigator.ts +121 -0
  266. package/src/data-structures/matrix/vector2d.ts +315 -0
  267. package/src/data-structures/priority-queue/index.ts +3 -0
  268. package/src/data-structures/priority-queue/max-priority-queue.ts +25 -0
  269. package/src/data-structures/priority-queue/min-priority-queue.ts +25 -0
  270. package/src/data-structures/priority-queue/priority-queue.ts +16 -0
  271. package/src/data-structures/queue/deque.ts +1073 -0
  272. package/src/data-structures/queue/index.ts +2 -0
  273. package/src/data-structures/queue/queue.ts +308 -0
  274. package/src/data-structures/stack/index.ts +1 -0
  275. package/src/data-structures/stack/stack.ts +150 -0
  276. package/src/data-structures/tree/index.ts +1 -0
  277. package/src/data-structures/tree/tree.ts +41 -0
  278. package/src/data-structures/trie/index.ts +1 -0
  279. package/src/data-structures/trie/trie.ts +345 -0
  280. package/src/index.ts +11 -0
  281. package/src/interfaces/binary-tree.ts +10 -0
  282. package/src/interfaces/doubly-linked-list.ts +1 -0
  283. package/src/interfaces/graph.ts +7 -0
  284. package/src/interfaces/heap.ts +1 -0
  285. package/src/interfaces/index.ts +8 -0
  286. package/src/interfaces/navigator.ts +1 -0
  287. package/src/interfaces/priority-queue.ts +1 -0
  288. package/src/interfaces/segment-tree.ts +1 -0
  289. package/src/interfaces/singly-linked-list.ts +1 -0
  290. package/src/types/common.ts +23 -0
  291. package/src/types/data-structures/binary-tree/avl-tree.ts +9 -0
  292. package/src/types/data-structures/binary-tree/binary-indexed-tree.ts +1 -0
  293. package/src/types/data-structures/binary-tree/binary-tree.ts +35 -0
  294. package/src/types/data-structures/binary-tree/bst.ts +13 -0
  295. package/src/types/data-structures/binary-tree/index.ts +6 -0
  296. package/src/types/data-structures/binary-tree/rb-tree.ts +10 -0
  297. package/src/types/data-structures/binary-tree/segment-tree.ts +1 -0
  298. package/src/types/data-structures/binary-tree/tree-multimap.ts +8 -0
  299. package/src/types/data-structures/graph/abstract-graph.ts +11 -0
  300. package/src/types/data-structures/graph/directed-graph.ts +2 -0
  301. package/src/types/data-structures/graph/index.ts +3 -0
  302. package/src/types/data-structures/graph/map-graph.ts +1 -0
  303. package/src/types/data-structures/graph/undirected-graph.ts +1 -0
  304. package/src/types/data-structures/hash/hash-map.ts +12 -0
  305. package/src/types/data-structures/hash/hash-table.ts +1 -0
  306. package/src/types/data-structures/hash/index.ts +4 -0
  307. package/src/types/data-structures/heap/heap.ts +1 -0
  308. package/src/types/data-structures/heap/index.ts +1 -0
  309. package/src/types/data-structures/heap/max-heap.ts +1 -0
  310. package/src/types/data-structures/heap/min-heap.ts +1 -0
  311. package/src/types/data-structures/index.ts +11 -0
  312. package/src/types/data-structures/linked-list/doubly-linked-list.ts +1 -0
  313. package/src/types/data-structures/linked-list/index.ts +2 -0
  314. package/src/types/data-structures/linked-list/singly-linked-list.ts +1 -0
  315. package/src/types/data-structures/linked-list/skip-linked-list.ts +1 -0
  316. package/src/types/data-structures/matrix/index.ts +1 -0
  317. package/src/types/data-structures/matrix/matrix.ts +1 -0
  318. package/src/types/data-structures/matrix/matrix2d.ts +1 -0
  319. package/src/types/data-structures/matrix/navigator.ts +14 -0
  320. package/src/types/data-structures/matrix/vector2d.ts +1 -0
  321. package/src/types/data-structures/priority-queue/index.ts +3 -0
  322. package/src/types/data-structures/priority-queue/max-priority-queue.ts +1 -0
  323. package/src/types/data-structures/priority-queue/min-priority-queue.ts +1 -0
  324. package/src/types/data-structures/priority-queue/priority-queue.ts +1 -0
  325. package/src/types/data-structures/queue/deque.ts +1 -0
  326. package/src/types/data-structures/queue/index.ts +2 -0
  327. package/src/types/data-structures/queue/queue.ts +1 -0
  328. package/src/types/data-structures/stack/index.ts +1 -0
  329. package/src/types/data-structures/stack/stack.ts +1 -0
  330. package/src/types/data-structures/tree/index.ts +1 -0
  331. package/src/types/data-structures/tree/tree.ts +1 -0
  332. package/src/types/data-structures/trie/index.ts +1 -0
  333. package/src/types/data-structures/trie/trie.ts +1 -0
  334. package/src/types/index.ts +3 -0
  335. package/src/types/utils/index.ts +2 -0
  336. package/src/types/utils/utils.ts +6 -0
  337. package/src/types/utils/validate-type.ts +35 -0
  338. package/src/utils/index.ts +1 -0
  339. package/src/utils/utils.ts +101 -0
  340. package/test/index.test.ts +111 -0
  341. package/tsconfig.json +38 -0
@@ -0,0 +1,1073 @@
1
+ /**
2
+ * data-structure-typed
3
+ *
4
+ * @author Tyler Zeng
5
+ * @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
6
+ * @license MIT License
7
+ */
8
+
9
+
10
+ import { IterableWithSizeOrLength } from "../../types";
11
+ import { calcMinUnitsRequired, rangeCheck } from "../../utils";
12
+
13
+ /**
14
+ * Deque can provide random access with O(1) time complexity
15
+ * Deque is usually more compact and efficient in memory usage because it does not require additional space to store pointers.
16
+ * Deque may experience performance jitter, but DoublyLinkedList will not
17
+ * Deque is implemented using a dynamic array. Inserting or deleting beyond both ends of the array may require moving elements or reallocating space.
18
+ */
19
+
20
+ export class Deque<E> {
21
+ protected _bucketFirst = 0;
22
+ protected _firstInBucket = 0;
23
+ protected _bucketLast = 0;
24
+ protected _lastInBucket = 0;
25
+ protected _bucketCount = 0;
26
+ protected readonly _bucketSize: number;
27
+
28
+ /**
29
+ * The constructor initializes a data structure with a specified bucket size and populates it with
30
+ * elements from an iterable.
31
+ * @param elements - The `elements` parameter is an iterable object (such as an array or a Set) that
32
+ * contains the initial elements to be stored in the data structure. It can also be an object with a
33
+ * `length` property or a `size` property, which represents the number of elements in the iterable.
34
+ * @param bucketSize - The `bucketSize` parameter is the maximum number of elements that can be
35
+ * stored in each bucket. It determines the size of each bucket in the data structure.
36
+ */
37
+ constructor(elements: IterableWithSizeOrLength<E> = [], bucketSize = (1 << 12)) {
38
+
39
+ let _size: number;
40
+ if ('length' in elements) {
41
+ if (elements.length instanceof Function) _size = elements.length(); else _size = elements.length;
42
+ } else {
43
+ if (elements.size instanceof Function) _size = elements.size(); else _size = elements.size;
44
+ }
45
+
46
+ this._bucketSize = bucketSize;
47
+ this._bucketCount = calcMinUnitsRequired(_size, this._bucketSize) || 1;
48
+ for (let i = 0; i < this._bucketCount; ++i) {
49
+ this._buckets.push(new Array(this._bucketSize));
50
+ }
51
+ const needBucketNum = calcMinUnitsRequired(_size, this._bucketSize);
52
+ this._bucketFirst = this._bucketLast = (this._bucketCount >> 1) - (needBucketNum >> 1);
53
+ this._firstInBucket = this._lastInBucket = (this._bucketSize - _size % this._bucketSize) >> 1;
54
+
55
+ for (const element of elements) {
56
+ this.push(element);
57
+ }
58
+ }
59
+
60
+ protected _buckets: E[][] = [];
61
+
62
+ get buckets() {
63
+ return this._buckets;
64
+ }
65
+
66
+ protected _size = 0;
67
+
68
+ get size() {
69
+ return this._size;
70
+ }
71
+
72
+ /**
73
+ * The function returns the first element in a collection if it exists, otherwise it returns
74
+ * undefined.
75
+ * @returns The first element of the collection, of type E, is being returned.
76
+ */
77
+ get first(): E | undefined {
78
+ if (this.size === 0) return;
79
+ return this._buckets[this._bucketFirst][this._firstInBucket];
80
+ }
81
+
82
+ get last(): E | undefined {
83
+ if (this.size === 0) return;
84
+ return this._buckets[this._bucketLast][this._lastInBucket];
85
+ }
86
+
87
+ /**
88
+ * Time Complexity: O(1) - Removes the last element.
89
+ * Space Complexity: O(1) - Operates in-place.
90
+ */
91
+
92
+ isEmpty() {
93
+ return this.size === 0;
94
+ }
95
+
96
+ /**
97
+ * Time Complexity: Amortized O(1) - Similar to push, resizing leads to O(n).
98
+ * Space Complexity: O(n) - Due to potential resizing.
99
+ */
100
+
101
+ /**
102
+ * Time Complexity: O(1)
103
+ * Space Complexity: O(n) - In worst case, resizing doubles the array size.
104
+ *
105
+ * The addLast function adds an element to the end of an array.
106
+ * @param {E} element - The element parameter represents the element that you want to add to the end of the
107
+ * data structure.
108
+ */
109
+ addLast(element: E): void {
110
+ this.push(element);
111
+ }
112
+
113
+ /**
114
+ * Time Complexity: O(1) - Removes the first element.
115
+ * Space Complexity: O(1) - In-place operation.
116
+ */
117
+
118
+ /**
119
+ * Time Complexity: O(1) - Removes the last element.
120
+ * Space Complexity: O(1) - Operates in-place.
121
+ *
122
+ * The function "popLast" removes and returns the last element of an array.
123
+ * @returns The last element of the array is being returned.
124
+ */
125
+ popLast(): E | undefined {
126
+ return this.pop();
127
+ }
128
+
129
+ /**
130
+ * Time Complexity: O(1).
131
+ * Space Complexity: O(n) - Due to potential resizing.
132
+ *
133
+ * The "addFirst" function adds an element to the beginning of an array.
134
+ * @param {E} element - The parameter "element" represents the element that you want to add to the
135
+ * beginning of the data structure.
136
+ */
137
+ addFirst(element: E): void {
138
+ this.unshift(element);
139
+ }
140
+
141
+ /**
142
+ * Time Complexity: O(1) - Removes the first element.
143
+ * Space Complexity: O(1) - In-place operation.
144
+ *
145
+ * The function "popFirst" removes and returns the first element of an array.
146
+ * @returns The method `popFirst()` is returning the first element of the array after removing it
147
+ * from the beginning. If the array is empty, it will return `undefined`.
148
+ */
149
+ popFirst(): E | undefined {
150
+ return this.shift();
151
+ }
152
+
153
+ /**
154
+ * The clear() function resets the state of the object by initializing all variables to their default
155
+ * values.
156
+ */
157
+ clear() {
158
+ this._buckets = [new Array(this._bucketSize)];
159
+ this._bucketCount = 1;
160
+ this._bucketFirst = this._bucketLast = this._size = 0;
161
+ this._firstInBucket = this._lastInBucket = this._bucketSize >> 1;
162
+ }
163
+
164
+ /**
165
+ * The below function is a generator that yields elements from a collection one by one.
166
+ */
167
+ * begin(): Generator<E> {
168
+ let index = 0;
169
+ while (index < this.size) {
170
+ yield this.getAt(index);
171
+ index++;
172
+ }
173
+ }
174
+
175
+ /**
176
+ * The function `reverseBegin()` is a generator that yields elements in reverse order starting from
177
+ * the last element.
178
+ */
179
+ * reverseBegin(): Generator<E> {
180
+ let index = this.size - 1;
181
+ while (index >= 0) {
182
+ yield this.getAt(index);
183
+ index--;
184
+ }
185
+ }
186
+
187
+ /**
188
+ * Time Complexity - Amortized O(1) (possible reallocation)
189
+ * Space Complexity - O(n) (due to potential resizing).
190
+ */
191
+
192
+ /**
193
+ * Time Complexity - Amortized O(1) (possible reallocation),
194
+ * Space Complexity - O(n) (due to potential resizing).
195
+ *
196
+ * The push function adds an element to a data structure and reallocates memory if necessary.
197
+ * @param {E} element - The `element` parameter represents the value that you want to add to the data
198
+ * structure.
199
+ * @returns The size of the data structure after the element has been pushed.
200
+ */
201
+ push(element: E) {
202
+ if (this.size) {
203
+ if (this._lastInBucket < this._bucketSize - 1) {
204
+ this._lastInBucket += 1;
205
+ } else if (this._bucketLast < this._bucketCount - 1) {
206
+ this._bucketLast += 1;
207
+ this._lastInBucket = 0;
208
+ } else {
209
+ this._bucketLast = 0;
210
+ this._lastInBucket = 0;
211
+ }
212
+ if (
213
+ this._bucketLast === this._bucketFirst &&
214
+ this._lastInBucket === this._firstInBucket
215
+ ) this._reallocate();
216
+ }
217
+ this._size += 1;
218
+ this._buckets[this._bucketLast][this._lastInBucket] = element;
219
+ return this.size;
220
+ }
221
+
222
+ /**
223
+ * Time Complexity: O(1)
224
+ * Space Complexity: O(1)
225
+ */
226
+
227
+ /**
228
+ * Time Complexity: O(1)
229
+ * Space Complexity: O(1)
230
+ *
231
+ * The `pop()` function removes and returns the last element from a data structure, updating the
232
+ * internal state variables accordingly.
233
+ * @returns The element that was removed from the data structure is being returned.
234
+ */
235
+ pop() {
236
+ if (this.size === 0) return;
237
+ const element = this._buckets[this._bucketLast][this._lastInBucket];
238
+ if (this.size !== 1) {
239
+ if (this._lastInBucket > 0) {
240
+ this._lastInBucket -= 1;
241
+ } else if (this._bucketLast > 0) {
242
+ this._bucketLast -= 1;
243
+ this._lastInBucket = this._bucketSize - 1;
244
+ } else {
245
+ this._bucketLast = this._bucketCount - 1;
246
+ this._lastInBucket = this._bucketSize - 1;
247
+ }
248
+ }
249
+ this._size -= 1;
250
+ return element;
251
+ }
252
+
253
+ /**
254
+ * Time Complexity: Amortized O(1)
255
+ * Space Complexity: O(n)
256
+ */
257
+
258
+ /**
259
+ * Time Complexity: Amortized O(1)
260
+ * Space Complexity: O(n)
261
+ *
262
+ * The `unshift` function adds an element to the beginning of an array-like data structure and
263
+ * returns the new size of the structure.
264
+ * @param {E} element - The `element` parameter represents the element that you want to add to the
265
+ * beginning of the data structure.
266
+ * @returns The size of the data structure after the element has been added.
267
+ */
268
+ unshift(element: E) {
269
+ if (this.size) {
270
+ if (this._firstInBucket > 0) {
271
+ this._firstInBucket -= 1;
272
+ } else if (this._bucketFirst > 0) {
273
+ this._bucketFirst -= 1;
274
+ this._firstInBucket = this._bucketSize - 1;
275
+ } else {
276
+ this._bucketFirst = this._bucketCount - 1;
277
+ this._firstInBucket = this._bucketSize - 1;
278
+ }
279
+ if (
280
+ this._bucketFirst === this._bucketLast &&
281
+ this._firstInBucket === this._lastInBucket
282
+ ) this._reallocate();
283
+ }
284
+ this._size += 1;
285
+ this._buckets[this._bucketFirst][this._firstInBucket] = element;
286
+ return this.size;
287
+ }
288
+
289
+
290
+ /**
291
+ * Time Complexity: O(1)
292
+ * Space Complexity: O(1)
293
+ */
294
+
295
+ /**
296
+ * Time Complexity: O(1)
297
+ * Space Complexity: O(1)
298
+ *
299
+ * The `shift()` function removes and returns the first element from a data structure, updating the
300
+ * internal state variables accordingly.
301
+ * @returns The element that is being removed from the beginning of the data structure is being
302
+ * returned.
303
+ */
304
+ shift() {
305
+ if (this.size === 0) return;
306
+ const element = this._buckets[this._bucketFirst][this._firstInBucket];
307
+ if (this.size !== 1) {
308
+ if (this._firstInBucket < this._bucketSize - 1) {
309
+ this._firstInBucket += 1;
310
+ } else if (this._bucketFirst < this._bucketCount - 1) {
311
+ this._bucketFirst += 1;
312
+ this._firstInBucket = 0;
313
+ } else {
314
+ this._bucketFirst = 0;
315
+ this._firstInBucket = 0;
316
+ }
317
+ }
318
+ this._size -= 1;
319
+ return element;
320
+ }
321
+
322
+
323
+ /**
324
+ * Time Complexity: O(1)
325
+ * Space Complexity: O(1)
326
+ */
327
+
328
+ /**
329
+ * Time Complexity: O(1)
330
+ * Space Complexity: O(1)
331
+ *
332
+ * The `getAt` function retrieves an element at a specified position in an array-like data structure.
333
+ * @param {number} pos - The `pos` parameter represents the position of the element that you want to
334
+ * retrieve from the data structure. It is of type `number` and should be a valid index within the
335
+ * range of the data structure.
336
+ * @returns The element at the specified position in the data structure is being returned.
337
+ */
338
+ getAt(pos: number): E {
339
+ rangeCheck(pos, 0, this.size - 1);
340
+ const {
341
+ bucketIndex,
342
+ indexInBucket
343
+ } = this._getBucketAndPosition(pos);
344
+ return this._buckets[bucketIndex][indexInBucket]!;
345
+ }
346
+
347
+
348
+ /**
349
+ * Time Complexity: O(1)
350
+ * Space Complexity: O(1)
351
+ */
352
+
353
+ /**
354
+ * Time Complexity: O(1)
355
+ * Space Complexity: O(1)
356
+ *
357
+ * The `setAt` function sets an element at a specific position in an array-like data structure.
358
+ * @param {number} pos - The `pos` parameter represents the position at which the element needs to be
359
+ * set. It is of type `number`.
360
+ * @param {E} element - The `element` parameter is the value that you want to set at the specified
361
+ * position in the data structure.
362
+ */
363
+ setAt(pos: number, element: E) {
364
+ rangeCheck(pos, 0, this.size - 1);
365
+ const {
366
+ bucketIndex,
367
+ indexInBucket
368
+ } = this._getBucketAndPosition(pos);
369
+ this._buckets[bucketIndex][indexInBucket] = element;
370
+ }
371
+
372
+ /**
373
+ * Time Complexity: O(n)
374
+ * Space Complexity: O(n)
375
+ */
376
+
377
+ /**
378
+ * Time Complexity: O(n)
379
+ * Space Complexity: O(n)
380
+ *
381
+ * The `insertAt` function inserts one or more elements at a specified position in an array-like data
382
+ * structure.
383
+ * @param {number} pos - The `pos` parameter represents the position at which the element(s) should
384
+ * be inserted. It is of type `number`.
385
+ * @param {E} element - The `element` parameter represents the element that you want to insert into
386
+ * the array at the specified position.
387
+ * @param [num=1] - The `num` parameter represents the number of times the `element` should be
388
+ * inserted at the specified position (`pos`). By default, it is set to 1, meaning that the `element`
389
+ * will be inserted once. However, you can provide a different value for `num` if you want
390
+ * @returns The size of the array after the insertion is being returned.
391
+ */
392
+ insertAt(pos: number, element: E, num = 1) {
393
+ const length = this.size;
394
+ rangeCheck(pos, 0, length);
395
+ if (pos === 0) {
396
+ while (num--) this.unshift(element);
397
+ } else if (pos === this.size) {
398
+ while (num--) this.push(element);
399
+ } else {
400
+ const arr: E[] = [];
401
+ for (let i = pos; i < this.size; ++i) {
402
+ arr.push(this.getAt(i));
403
+ }
404
+ this.cut(pos - 1);
405
+ for (let i = 0; i < num; ++i) this.push(element);
406
+ for (let i = 0; i < arr.length; ++i) this.push(arr[i]);
407
+ }
408
+ return this.size;
409
+ }
410
+
411
+ /**
412
+ * Time Complexity: O(1)
413
+ * Space Complexity: O(1)
414
+ */
415
+
416
+ /**
417
+ * Time Complexity: O(1)
418
+ * Space Complexity: O(1)
419
+ *
420
+ * The `cut` function updates the state of the object based on the given position and returns the
421
+ * updated size.
422
+ * @param {number} pos - The `pos` parameter represents the position at which the string should be
423
+ * cut. It is a number that indicates the index of the character where the cut should be made.
424
+ * @returns The method is returning the updated size of the data structure.
425
+ */
426
+ cut(pos: number) {
427
+ if (pos < 0) {
428
+ this.clear();
429
+ return 0;
430
+ }
431
+ const {
432
+ bucketIndex,
433
+ indexInBucket
434
+ } = this._getBucketAndPosition(pos);
435
+ this._bucketLast = bucketIndex;
436
+ this._lastInBucket = indexInBucket;
437
+ this._size = pos + 1;
438
+ return this.size;
439
+ }
440
+
441
+ /**
442
+ * Time Complexity: O(n)
443
+ * Space Complexity: O(1)
444
+ */
445
+
446
+ /**
447
+ * Time Complexity: O(n)
448
+ * Space Complexity: O(1)
449
+ *
450
+ * The `deleteAt` function removes an element at a specified position in an array-like data
451
+ * structure.
452
+ * @param {number} pos - The `pos` parameter in the `deleteAt` function represents the position at
453
+ * which an element needs to be deleted from the data structure. It is of type `number` and indicates
454
+ * the index of the element to be deleted.
455
+ * @returns The size of the data structure after the deletion operation is performed.
456
+ */
457
+ deleteAt(pos: number) {
458
+ rangeCheck(pos, 0, this.size - 1);
459
+ if (pos === 0) this.shift();
460
+ else if (pos === this.size - 1) this.pop();
461
+ else {
462
+ const length = this.size - 1;
463
+ let {
464
+ bucketIndex: curBucket,
465
+ indexInBucket: curPointer
466
+ } = this._getBucketAndPosition(pos);
467
+ for (let i = pos; i < length; ++i) {
468
+ const {
469
+ bucketIndex: nextBucket,
470
+ indexInBucket: nextPointer
471
+ } = this._getBucketAndPosition(pos + 1);
472
+ this._buckets[curBucket][curPointer] = this._buckets[nextBucket][nextPointer];
473
+ curBucket = nextBucket;
474
+ curPointer = nextPointer;
475
+ }
476
+ this.pop();
477
+ }
478
+ return this.size;
479
+ }
480
+
481
+ /**
482
+ * Time Complexity: O(n)
483
+ * Space Complexity: O(1)
484
+ */
485
+
486
+ /**
487
+ * Time Complexity: O(n)
488
+ * Space Complexity: O(1)
489
+ *
490
+ * The `delete` function removes all occurrences of a specified element from an array-like data
491
+ * structure.
492
+ * @param {E} element - The `element` parameter represents the element that you want to delete from
493
+ * the data structure.
494
+ * @returns The size of the data structure after the element has been deleted.
495
+ */
496
+ delete(element: E) {
497
+ const size = this.size;
498
+ if (size === 0) return 0;
499
+ let i = 0;
500
+ let index = 0;
501
+ while (i < size) {
502
+ const oldElement = this.getAt(i);
503
+ if (oldElement !== element) {
504
+ this.setAt(index, oldElement!);
505
+ index += 1;
506
+ }
507
+ i += 1;
508
+ }
509
+ this.cut(index - 1);
510
+ return this.size;
511
+ }
512
+
513
+ /**
514
+ * Time Complexity: O(n)
515
+ * Space Complexity: O(1)
516
+ */
517
+
518
+ /**
519
+ * Time Complexity: O(n)
520
+ * Space Complexity: O(1)
521
+ *
522
+ * The reverse() function reverses the order of the buckets and the elements within each bucket in a
523
+ * data structure.
524
+ * @returns The reverse() method is returning the object itself (this) after performing the reverse
525
+ * operation on the buckets and updating the relevant properties.
526
+ */
527
+ reverse() {
528
+ this._buckets.reverse().forEach(function (bucket) {
529
+ bucket.reverse();
530
+ });
531
+ const { _bucketFirst, _bucketLast, _firstInBucket, _lastInBucket } = this;
532
+ this._bucketFirst = this._bucketCount - _bucketLast - 1;
533
+ this._bucketLast = this._bucketCount - _bucketFirst - 1;
534
+ this._firstInBucket = this._bucketSize - _lastInBucket - 1;
535
+ this._lastInBucket = this._bucketSize - _firstInBucket - 1;
536
+ return this;
537
+ }
538
+
539
+ /**
540
+ * Time Complexity: O(n)
541
+ * Space Complexity: O(1)
542
+ */
543
+
544
+ /**
545
+ * Time Complexity: O(n)
546
+ * Space Complexity: O(1)
547
+ *
548
+ * The `unique()` function removes duplicate elements from an array-like data structure and returns
549
+ * the number of unique elements.
550
+ * @returns The size of the modified array is being returned.
551
+ */
552
+ unique() {
553
+ if (this.size <= 1) {
554
+ return this.size;
555
+ }
556
+ let index = 1;
557
+ let prev = this.getAt(0);
558
+ for (let i = 1; i < this.size; ++i) {
559
+ const cur = this.getAt(i);
560
+ if (cur !== prev) {
561
+ prev = cur;
562
+ this.setAt(index++, cur);
563
+ }
564
+ }
565
+ this.cut(index - 1);
566
+ return this.size;
567
+ }
568
+
569
+ /**
570
+ * Time Complexity: O(n log n)
571
+ * Space Complexity: O(n)
572
+ */
573
+
574
+ /**
575
+ * Time Complexity: O(n log n)
576
+ * Space Complexity: O(n)
577
+ *
578
+ * The `sort` function sorts the elements in a data structure using a provided comparator function.
579
+ * @param [comparator] - The `comparator` parameter is a function that takes in two elements `x` and
580
+ * `y` of type `E` and returns a number. The comparator function is used to determine the order of
581
+ * the elements in the sorted array.
582
+ * @returns The method is returning the sorted instance of the object on which the method is called.
583
+ */
584
+ sort(comparator?: (x: E, y: E) => number) {
585
+ const arr: E[] = [];
586
+ for (let i = 0; i < this.size; ++i) {
587
+ arr.push(this.getAt(i));
588
+ }
589
+ arr.sort(comparator);
590
+ for (let i = 0; i < this.size; ++i) {
591
+ this.setAt(i, arr[i]);
592
+ }
593
+ return this;
594
+ }
595
+
596
+ /**
597
+ * Time Complexity: O(n)
598
+ * Space Complexity: O(n)
599
+ */
600
+
601
+ /**
602
+ * Time Complexity: O(n)
603
+ * Space Complexity: O(n)
604
+ *
605
+ * The `shrinkToFit` function reorganizes the elements in an array-like data structure to minimize
606
+ * memory usage.
607
+ * @returns Nothing is being returned. The function is using the `return` statement to exit early if
608
+ * `this.size` is 0, but it does not return any value.
609
+ */
610
+ shrinkToFit() {
611
+ if (this.size === 0) return;
612
+ const newBuckets = [];
613
+ if (this._bucketFirst === this._bucketLast) return;
614
+ else if (this._bucketFirst < this._bucketLast) {
615
+ for (let i = this._bucketFirst; i <= this._bucketLast; ++i) {
616
+ newBuckets.push(this._buckets[i]);
617
+ }
618
+ } else {
619
+ for (let i = this._bucketFirst; i < this._bucketCount; ++i) {
620
+ newBuckets.push(this._buckets[i]);
621
+ }
622
+ for (let i = 0; i <= this._bucketLast; ++i) {
623
+ newBuckets.push(this._buckets[i]);
624
+ }
625
+ }
626
+ this._bucketFirst = 0;
627
+ this._bucketLast = newBuckets.length - 1;
628
+ this._buckets = newBuckets;
629
+ }
630
+
631
+ /**
632
+ * Time Complexity: O(n)
633
+ * Space Complexity: O(1)
634
+ */
635
+
636
+ /**
637
+ * Time Complexity: O(n)
638
+ * Space Complexity: O(1)
639
+ *
640
+ * The `forEach` function iterates over each element in a deque and applies a callback function to
641
+ * each element.
642
+ * @param callback - The callback parameter is a function that will be called for each element in the
643
+ * deque. It takes three parameters:
644
+ */
645
+ forEach(callback: (element: E, index: number, deque: Deque<E>) => void) {
646
+ for (let i = 0; i < this.size; ++i) {
647
+ callback(this.getAt(i), i, this);
648
+ }
649
+ }
650
+
651
+ /**
652
+ * Time Complexity: O(n)
653
+ * Space Complexity: O(1)
654
+ */
655
+
656
+ /**
657
+ * Time Complexity: O(n)
658
+ * Space Complexity: O(1)
659
+ *
660
+ * The `find` function iterates over the elements in a deque and returns the first element for which
661
+ * the callback function returns true, or undefined if no such element is found.
662
+ * @param callback - A function that takes three parameters: element, index, and deque. It should
663
+ * return a boolean value indicating whether the element satisfies a certain condition.
664
+ * @returns The method `find` returns the first element in the deque that satisfies the condition
665
+ * specified by the callback function. If no element satisfies the condition, it returns `undefined`.
666
+ */
667
+ find(callback: (element: E, index: number, deque: Deque<E>) => boolean): E | undefined {
668
+ for (let i = 0; i < this.size; ++i) {
669
+ const element = this.getAt(i);
670
+ if (callback(element, i, this)) {
671
+ return element;
672
+ }
673
+ }
674
+ return undefined;
675
+ }
676
+
677
+ /**
678
+ * Time Complexity: O(n)
679
+ * Space Complexity: O(n)
680
+ */
681
+
682
+ /**
683
+ * Time Complexity: O(n)
684
+ * Space Complexity: O(n)
685
+ *
686
+ * The `toArray` function converts the elements of a data structure into an array.
687
+ * @returns The `toArray()` method is returning an array of elements of type `E`.
688
+ */
689
+ toArray(): E[] {
690
+ const arr: E[] = [];
691
+ for (let i = 0; i < this.size; ++i) {
692
+ arr.push(this.getAt(i));
693
+ }
694
+ return arr;
695
+ }
696
+
697
+ /**
698
+ * Time Complexity: O(n)
699
+ * Space Complexity: O(n)
700
+ */
701
+
702
+ /**
703
+ * Time Complexity: O(n)
704
+ * Space Complexity: O(n)
705
+ *
706
+ * The `map` function takes a callback function and applies it to each element in the deque,
707
+ * returning a new deque with the results.
708
+ * @param callback - The `callback` parameter is a function that takes three arguments:
709
+ * @returns The `map` method is returning a new `Deque` object with the transformed elements.
710
+ */
711
+ map<T>(callback: (element: E, index: number, deque: Deque<E>) => T): Deque<T> {
712
+ const newDeque = new Deque<T>([], this._bucketSize);
713
+ for (let i = 0; i < this.size; ++i) {
714
+ newDeque.push(callback(this.getAt(i), i, this));
715
+ }
716
+ return newDeque;
717
+ }
718
+
719
+ /**
720
+ * Time Complexity: O(n)
721
+ * Space Complexity: O(n)
722
+ */
723
+
724
+ /**
725
+ * Time Complexity: O(n)
726
+ * Space Complexity: O(n)
727
+ *
728
+ * The `filter` function creates a new deque containing only the elements that satisfy the given
729
+ * predicate function.
730
+ * @param predicate - The `predicate` parameter is a function that takes three arguments: `element`,
731
+ * `index`, and `deque`.
732
+ * @returns The `filter` method is returning a new `Deque` object that contains only the elements
733
+ * that satisfy the given `predicate` function.
734
+ */
735
+ filter(predicate: (element: E, index: number, deque: Deque<E>) => boolean): Deque<E> {
736
+ const newDeque = new Deque<E>([], this._bucketSize);
737
+ for (let i = 0; i < this.size; ++i) {
738
+ const element = this.getAt(i);
739
+ if (predicate(element, i, this)) {
740
+ newDeque.push(element);
741
+ }
742
+ }
743
+ return newDeque;
744
+ }
745
+
746
+ /**
747
+ * Time Complexity: O(n)
748
+ * Space Complexity: O(1)
749
+ */
750
+
751
+ /**
752
+ * Time Complexity: O(n)
753
+ * Space Complexity: O(1)
754
+ *
755
+ * The `reduce` function iterates over the elements of a deque and applies a callback function to
756
+ * each element, accumulating a single value.
757
+ * @param callback - The `callback` parameter is a function that takes four arguments:
758
+ * @param {T} initialValue - The `initialValue` parameter is the initial value of the accumulator. It
759
+ * is the value that will be passed as the first argument to the `callback` function when reducing
760
+ * the elements of the deque.
761
+ * @returns the final value of the accumulator after iterating over all elements in the deque and
762
+ * applying the callback function to each element.
763
+ */
764
+ reduce<T>(callback: (accumulator: T, element: E, index: number, deque: Deque<E>) => T, initialValue: T): T {
765
+ let accumulator = initialValue;
766
+ for (let i = 0; i < this.size; ++i) {
767
+ accumulator = callback(accumulator, this.getAt(i), i, this);
768
+ }
769
+ return accumulator;
770
+ }
771
+
772
+ /**
773
+ * Time Complexity: O(n)
774
+ * Space Complexity: O(1)
775
+ */
776
+
777
+ /**
778
+ * Time Complexity: O(n)
779
+ * Space Complexity: O(1)
780
+ *
781
+ * The function "indexOf" returns the index of the first occurrence of a given element in an array,
782
+ * or -1 if the element is not found.
783
+ * @param {E} element - The "element" parameter represents the element that you want to find the
784
+ * index of in the data structure.
785
+ * @returns The indexOf function returns the index of the first occurrence of the specified element
786
+ * in the data structure. If the element is not found, it returns -1.
787
+ */
788
+ indexOf(element: E): number {
789
+ for (let i = 0; i < this.size; ++i) {
790
+ if (this.getAt(i) === element) {
791
+ return i;
792
+ }
793
+ }
794
+ return -1;
795
+ }
796
+
797
+ /**
798
+ * Time Complexity: O(n)
799
+ * Space Complexity: O(1)
800
+ */
801
+
802
+ /**
803
+ * Time Complexity: O(n)
804
+ * Space Complexity: O(1)
805
+ *
806
+ * The above function is an implementation of the iterator protocol in TypeScript, allowing the
807
+ * object to be iterated over using a for...of loop.
808
+ */
809
+ * [Symbol.iterator]() {
810
+ for (let i = 0; i < this.size; ++i) {
811
+ yield this.getAt(i);
812
+ }
813
+ }
814
+
815
+ /**
816
+ * Time Complexity: O(n)
817
+ * Space Complexity: O(n)
818
+ */
819
+
820
+ /**
821
+ * Time Complexity: O(n)
822
+ * Space Complexity: O(n)
823
+ *
824
+ * The `_reallocate` function reallocates the buckets in an array, adding new buckets if needed.
825
+ * @param {number} [needBucketNum] - The `needBucketNum` parameter is an optional number that
826
+ * specifies the number of new buckets needed. If not provided, it will default to half of the
827
+ * current bucket count (`this._bucketCount >> 1`) or 1 if the current bucket count is less than 2.
828
+ */
829
+ protected _reallocate(needBucketNum?: number) {
830
+ const newBuckets = [];
831
+ const addBucketNum = needBucketNum || this._bucketCount >> 1 || 1;
832
+ for (let i = 0; i < addBucketNum; ++i) {
833
+ newBuckets[i] = new Array(this._bucketSize);
834
+ }
835
+ for (let i = this._bucketFirst; i < this._bucketCount; ++i) {
836
+ newBuckets[newBuckets.length] = this._buckets[i];
837
+ }
838
+ for (let i = 0; i < this._bucketLast; ++i) {
839
+ newBuckets[newBuckets.length] = this._buckets[i];
840
+ }
841
+ newBuckets[newBuckets.length] = [...this._buckets[this._bucketLast]];
842
+ this._bucketFirst = addBucketNum;
843
+ this._bucketLast = newBuckets.length - 1;
844
+ for (let i = 0; i < addBucketNum; ++i) {
845
+ newBuckets[newBuckets.length] = new Array(this._bucketSize);
846
+ }
847
+ this._buckets = newBuckets;
848
+ this._bucketCount = newBuckets.length;
849
+ }
850
+
851
+ /**
852
+ * Time Complexity: O(1)
853
+ * Space Complexity: O(1)
854
+ */
855
+
856
+ /**
857
+ * Time Complexity: O(1)
858
+ * Space Complexity: O(1)
859
+ *
860
+ * The function calculates the bucket index and index within the bucket based on the given position.
861
+ * @param {number} pos - The `pos` parameter represents the position within the data structure. It is
862
+ * a number that indicates the index or position of an element within the structure.
863
+ * @returns an object with two properties: "bucketIndex" and "indexInBucket".
864
+ */
865
+ protected _getBucketAndPosition(pos: number) {
866
+ let bucketIndex: number;
867
+ let indexInBucket: number;
868
+
869
+ const overallIndex = this._firstInBucket + pos;
870
+ bucketIndex = this._bucketFirst + Math.floor(overallIndex / this._bucketSize);
871
+
872
+ if (bucketIndex >= this._bucketCount) {
873
+ bucketIndex -= this._bucketCount;
874
+ }
875
+
876
+ indexInBucket = (overallIndex + 1) % this._bucketSize - 1;
877
+ if (indexInBucket < 0) {
878
+ indexInBucket = this._bucketSize - 1;
879
+ }
880
+
881
+ return { bucketIndex, indexInBucket };
882
+ }
883
+ }
884
+
885
+ // O(1) time complexity of obtaining the element
886
+ // O(n) time complexity of adding at the beginning and the end
887
+ // todo tested slowest one
888
+ export class ObjectDeque<E = number> {
889
+ constructor(capacity?: number) {
890
+ if (capacity !== undefined) this._capacity = capacity;
891
+ }
892
+
893
+ protected _nodes: { [key: number]: E } = {};
894
+
895
+ get nodes(): { [p: number]: E } {
896
+ return this._nodes;
897
+ }
898
+
899
+ protected _capacity = Number.MAX_SAFE_INTEGER;
900
+
901
+ get capacity(): number {
902
+ return this._capacity;
903
+ }
904
+
905
+ protected _first = -1;
906
+
907
+ get first(): number {
908
+ return this._first;
909
+ }
910
+
911
+ protected _last = -1;
912
+
913
+ get last(): number {
914
+ return this._last;
915
+ }
916
+
917
+ protected _size = 0;
918
+
919
+ get size(): number {
920
+ return this._size;
921
+ }
922
+
923
+ /**
924
+ * Time Complexity: O(1)
925
+ * Space Complexity: O(1)
926
+ */
927
+
928
+ /**
929
+ * Time Complexity: O(1)
930
+ * Space Complexity: O(1)
931
+ *
932
+ * The "addFirst" function adds an element to the beginning of an array-like data structure.
933
+ * @param {E} element - The `element` parameter represents the element that you want to add to the beginning of the data
934
+ * structure.
935
+ */
936
+ addFirst(element: E) {
937
+ if (this.size === 0) {
938
+ const mid = Math.floor(this.capacity / 2);
939
+ this._first = mid;
940
+ this._last = mid;
941
+ } else {
942
+ this._first--;
943
+ }
944
+ this.nodes[this.first] = element;
945
+ this._size++;
946
+ }
947
+
948
+ /**
949
+ * Time Complexity: O(1)
950
+ * Space Complexity: O(1)
951
+ */
952
+
953
+ /**
954
+ * Time Complexity: O(1)
955
+ * Space Complexity: O(1)
956
+ *
957
+ * The addLast function adds an element to the end of an array-like data structure.
958
+ * @param {E} element - The `element` parameter represents the element that you want to add to the end of the data structure.
959
+ */
960
+ addLast(element: E) {
961
+ if (this.size === 0) {
962
+ const mid = Math.floor(this.capacity / 2);
963
+ this._first = mid;
964
+ this._last = mid;
965
+ } else {
966
+ this._last++;
967
+ }
968
+ this.nodes[this.last] = element;
969
+ this._size++;
970
+ }
971
+
972
+ /**
973
+ * Time Complexity: O(1)
974
+ * Space Complexity: O(1)
975
+ */
976
+
977
+ /**
978
+ * Time Complexity: O(1)
979
+ * Space Complexity: O(1)
980
+ *
981
+ * The function `popFirst()` removes and returns the first element in a data structure.
982
+ * @returns The element of the first element in the data structure.
983
+ */
984
+ popFirst() {
985
+ if (!this.size) return;
986
+ const element = this.getFirst();
987
+ delete this.nodes[this.first];
988
+ this._first++;
989
+ this._size--;
990
+ return element;
991
+ }
992
+
993
+ /**
994
+ * Time Complexity: O(1)
995
+ * Space Complexity: O(1)
996
+ */
997
+
998
+ /**
999
+ * Time Complexity: O(1)
1000
+ * Space Complexity: O(1)
1001
+ *
1002
+ * The `getFirst` function returns the first element in an array-like data structure if it exists.
1003
+ * @returns The element at the first position of the `_nodes` array.
1004
+ */
1005
+ getFirst() {
1006
+ if (this.size) return this.nodes[this.first];
1007
+ }
1008
+
1009
+ /**
1010
+ * Time Complexity: O(1)
1011
+ * Space Complexity: O(1)
1012
+ */
1013
+
1014
+ /**
1015
+ * Time Complexity: O(1)
1016
+ * Space Complexity: O(1)
1017
+ *
1018
+ * The `popLast()` function removes and returns the last element in a data structure.
1019
+ * @returns The element that was removed from the data structure.
1020
+ */
1021
+ popLast() {
1022
+ if (!this.size) return;
1023
+ const element = this.getLast();
1024
+ delete this.nodes[this.last];
1025
+ this._last--;
1026
+ this._size--;
1027
+
1028
+ return element;
1029
+ }
1030
+
1031
+ /**
1032
+ * Time Complexity: O(1)
1033
+ * Space Complexity: O(1)
1034
+ */
1035
+
1036
+ /**
1037
+ * Time Complexity: O(1)
1038
+ * Space Complexity: O(1)
1039
+ *
1040
+ * The `getLast()` function returns the last element in an array-like data structure.
1041
+ * @returns The last element in the array "_nodes" is being returned.
1042
+ */
1043
+ getLast() {
1044
+ if (this.size) return this.nodes[this.last];
1045
+ }
1046
+
1047
+ /**
1048
+ * Time Complexity: O(1)
1049
+ * Space Complexity: O(1)
1050
+ */
1051
+
1052
+ /**
1053
+ * Time Complexity: O(1)
1054
+ * Space Complexity: O(1)
1055
+ *
1056
+ * The get function returns the element at the specified index in an array-like data structure.
1057
+ * @param {number} index - The index parameter is a number that represents the position of the element you want to
1058
+ * retrieve from the array.
1059
+ * @returns The element at the specified index in the `_nodes` array is being returned. If there is no element at that
1060
+ * index, `undefined` is returned.
1061
+ */
1062
+ get(index: number) {
1063
+ return this.nodes[this.first + index] || undefined;
1064
+ }
1065
+
1066
+ /**
1067
+ * The function checks if the size of a data structure is less than or equal to zero.
1068
+ * @returns The method is returning a boolean element indicating whether the size of the object is less than or equal to 0.
1069
+ */
1070
+ isEmpty() {
1071
+ return this.size <= 0;
1072
+ }
1073
+ }