splay.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694
  1. /**
  2. * splaytree v3.1.2
  3. * Fast Splay tree for Node and browser
  4. *
  5. * @author Alexander Milevski <info@w8r.name>
  6. * @license MIT
  7. * @preserve
  8. */
  9. (function (global, factory) {
  10. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  11. typeof define === 'function' && define.amd ? define(factory) :
  12. (global.SplayTree = factory());
  13. }(this, (function () { 'use strict';
  14. /*! *****************************************************************************
  15. Copyright (c) Microsoft Corporation. All rights reserved.
  16. Licensed under the Apache License, Version 2.0 (the "License"); you may not use
  17. this file except in compliance with the License. You may obtain a copy of the
  18. License at http://www.apache.org/licenses/LICENSE-2.0
  19. THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  20. KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
  21. WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
  22. MERCHANTABLITY OR NON-INFRINGEMENT.
  23. See the Apache Version 2.0 License for specific language governing permissions
  24. and limitations under the License.
  25. ***************************************************************************** */
  26. function __generator(thisArg, body) {
  27. var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
  28. return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
  29. function verb(n) { return function (v) { return step([n, v]); }; }
  30. function step(op) {
  31. if (f) throw new TypeError("Generator is already executing.");
  32. while (_) try {
  33. if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
  34. if (y = 0, t) op = [op[0] & 2, t.value];
  35. switch (op[0]) {
  36. case 0: case 1: t = op; break;
  37. case 4: _.label++; return { value: op[1], done: false };
  38. case 5: _.label++; y = op[1]; op = [0]; continue;
  39. case 7: op = _.ops.pop(); _.trys.pop(); continue;
  40. default:
  41. if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
  42. if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
  43. if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
  44. if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
  45. if (t[2]) _.ops.pop();
  46. _.trys.pop(); continue;
  47. }
  48. op = body.call(thisArg, _);
  49. } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
  50. if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
  51. }
  52. }
  53. var Node = /** @class */ (function () {
  54. function Node(key, data) {
  55. this.next = null;
  56. this.key = key;
  57. this.data = data;
  58. this.left = null;
  59. this.right = null;
  60. }
  61. return Node;
  62. }());
  63. /* follows "An implementation of top-down splaying"
  64. * by D. Sleator <sleator@cs.cmu.edu> March 1992
  65. */
  66. function DEFAULT_COMPARE(a, b) {
  67. return a > b ? 1 : a < b ? -1 : 0;
  68. }
  69. /**
  70. * Simple top down splay, not requiring i to be in the tree t.
  71. */
  72. function splay(i, t, comparator) {
  73. var N = new Node(null, null);
  74. var l = N;
  75. var r = N;
  76. while (true) {
  77. var cmp = comparator(i, t.key);
  78. //if (i < t.key) {
  79. if (cmp < 0) {
  80. if (t.left === null)
  81. break;
  82. //if (i < t.left.key) {
  83. if (comparator(i, t.left.key) < 0) {
  84. var y = t.left; /* rotate right */
  85. t.left = y.right;
  86. y.right = t;
  87. t = y;
  88. if (t.left === null)
  89. break;
  90. }
  91. r.left = t; /* link right */
  92. r = t;
  93. t = t.left;
  94. //} else if (i > t.key) {
  95. }
  96. else if (cmp > 0) {
  97. if (t.right === null)
  98. break;
  99. //if (i > t.right.key) {
  100. if (comparator(i, t.right.key) > 0) {
  101. var y = t.right; /* rotate left */
  102. t.right = y.left;
  103. y.left = t;
  104. t = y;
  105. if (t.right === null)
  106. break;
  107. }
  108. l.right = t; /* link left */
  109. l = t;
  110. t = t.right;
  111. }
  112. else
  113. break;
  114. }
  115. /* assemble */
  116. l.right = t.left;
  117. r.left = t.right;
  118. t.left = N.right;
  119. t.right = N.left;
  120. return t;
  121. }
  122. function insert(i, data, t, comparator) {
  123. var node = new Node(i, data);
  124. if (t === null) {
  125. node.left = node.right = null;
  126. return node;
  127. }
  128. t = splay(i, t, comparator);
  129. var cmp = comparator(i, t.key);
  130. if (cmp < 0) {
  131. node.left = t.left;
  132. node.right = t;
  133. t.left = null;
  134. }
  135. else if (cmp >= 0) {
  136. node.right = t.right;
  137. node.left = t;
  138. t.right = null;
  139. }
  140. return node;
  141. }
  142. function split(key, v, comparator) {
  143. var left = null;
  144. var right = null;
  145. if (v) {
  146. v = splay(key, v, comparator);
  147. var cmp = comparator(v.key, key);
  148. if (cmp === 0) {
  149. left = v.left;
  150. right = v.right;
  151. }
  152. else if (cmp < 0) {
  153. right = v.right;
  154. v.right = null;
  155. left = v;
  156. }
  157. else {
  158. left = v.left;
  159. v.left = null;
  160. right = v;
  161. }
  162. }
  163. return { left: left, right: right };
  164. }
  165. function merge(left, right, comparator) {
  166. if (right === null)
  167. return left;
  168. if (left === null)
  169. return right;
  170. right = splay(left.key, right, comparator);
  171. right.left = left;
  172. return right;
  173. }
  174. /**
  175. * Prints level of the tree
  176. */
  177. function printRow(root, prefix, isTail, out, printNode) {
  178. if (root) {
  179. out("" + prefix + (isTail ? '└── ' : '├── ') + printNode(root) + "\n");
  180. var indent = prefix + (isTail ? ' ' : '│ ');
  181. if (root.left)
  182. printRow(root.left, indent, false, out, printNode);
  183. if (root.right)
  184. printRow(root.right, indent, true, out, printNode);
  185. }
  186. }
  187. var Tree = /** @class */ (function () {
  188. function Tree(comparator) {
  189. if (comparator === void 0) { comparator = DEFAULT_COMPARE; }
  190. this._root = null;
  191. this._size = 0;
  192. this._comparator = comparator;
  193. }
  194. /**
  195. * Inserts a key, allows duplicates
  196. */
  197. Tree.prototype.insert = function (key, data) {
  198. this._size++;
  199. return this._root = insert(key, data, this._root, this._comparator);
  200. };
  201. /**
  202. * Adds a key, if it is not present in the tree
  203. */
  204. Tree.prototype.add = function (key, data) {
  205. var node = new Node(key, data);
  206. if (this._root === null) {
  207. node.left = node.right = null;
  208. this._size++;
  209. this._root = node;
  210. }
  211. var comparator = this._comparator;
  212. var t = splay(key, this._root, comparator);
  213. var cmp = comparator(key, t.key);
  214. if (cmp === 0)
  215. this._root = t;
  216. else {
  217. if (cmp < 0) {
  218. node.left = t.left;
  219. node.right = t;
  220. t.left = null;
  221. }
  222. else if (cmp > 0) {
  223. node.right = t.right;
  224. node.left = t;
  225. t.right = null;
  226. }
  227. this._size++;
  228. this._root = node;
  229. }
  230. return this._root;
  231. };
  232. /**
  233. * @param {Key} key
  234. * @return {Node|null}
  235. */
  236. Tree.prototype.remove = function (key) {
  237. this._root = this._remove(key, this._root, this._comparator);
  238. };
  239. /**
  240. * Deletes i from the tree if it's there
  241. */
  242. Tree.prototype._remove = function (i, t, comparator) {
  243. var x;
  244. if (t === null)
  245. return null;
  246. t = splay(i, t, comparator);
  247. var cmp = comparator(i, t.key);
  248. if (cmp === 0) { /* found it */
  249. if (t.left === null) {
  250. x = t.right;
  251. }
  252. else {
  253. x = splay(i, t.left, comparator);
  254. x.right = t.right;
  255. }
  256. this._size--;
  257. return x;
  258. }
  259. return t; /* It wasn't there */
  260. };
  261. /**
  262. * Removes and returns the node with smallest key
  263. */
  264. Tree.prototype.pop = function () {
  265. var node = this._root;
  266. if (node) {
  267. while (node.left)
  268. node = node.left;
  269. this._root = splay(node.key, this._root, this._comparator);
  270. this._root = this._remove(node.key, this._root, this._comparator);
  271. return { key: node.key, data: node.data };
  272. }
  273. return null;
  274. };
  275. /**
  276. * Find without splaying
  277. */
  278. Tree.prototype.findStatic = function (key) {
  279. var current = this._root;
  280. var compare = this._comparator;
  281. while (current) {
  282. var cmp = compare(key, current.key);
  283. if (cmp === 0)
  284. return current;
  285. else if (cmp < 0)
  286. current = current.left;
  287. else
  288. current = current.right;
  289. }
  290. return null;
  291. };
  292. Tree.prototype.find = function (key) {
  293. if (this._root) {
  294. this._root = splay(key, this._root, this._comparator);
  295. if (this._comparator(key, this._root.key) !== 0)
  296. return null;
  297. }
  298. return this._root;
  299. };
  300. Tree.prototype.contains = function (key) {
  301. var current = this._root;
  302. var compare = this._comparator;
  303. while (current) {
  304. var cmp = compare(key, current.key);
  305. if (cmp === 0)
  306. return true;
  307. else if (cmp < 0)
  308. current = current.left;
  309. else
  310. current = current.right;
  311. }
  312. return false;
  313. };
  314. Tree.prototype.forEach = function (visitor, ctx) {
  315. var current = this._root;
  316. var Q = []; /* Initialize stack s */
  317. var done = false;
  318. while (!done) {
  319. if (current !== null) {
  320. Q.push(current);
  321. current = current.left;
  322. }
  323. else {
  324. if (Q.length !== 0) {
  325. current = Q.pop();
  326. visitor.call(ctx, current);
  327. current = current.right;
  328. }
  329. else
  330. done = true;
  331. }
  332. }
  333. return this;
  334. };
  335. /**
  336. * Walk key range from `low` to `high`. Stops if `fn` returns a value.
  337. */
  338. Tree.prototype.range = function (low, high, fn, ctx) {
  339. var Q = [];
  340. var compare = this._comparator;
  341. var node = this._root;
  342. var cmp;
  343. while (Q.length !== 0 || node) {
  344. if (node) {
  345. Q.push(node);
  346. node = node.left;
  347. }
  348. else {
  349. node = Q.pop();
  350. cmp = compare(node.key, high);
  351. if (cmp > 0) {
  352. break;
  353. }
  354. else if (compare(node.key, low) >= 0) {
  355. if (fn.call(ctx, node))
  356. return this; // stop if smth is returned
  357. }
  358. node = node.right;
  359. }
  360. }
  361. return this;
  362. };
  363. /**
  364. * Returns array of keys
  365. */
  366. Tree.prototype.keys = function () {
  367. var keys = [];
  368. this.forEach(function (_a) {
  369. var key = _a.key;
  370. return keys.push(key);
  371. });
  372. return keys;
  373. };
  374. /**
  375. * Returns array of all the data in the nodes
  376. */
  377. Tree.prototype.values = function () {
  378. var values = [];
  379. this.forEach(function (_a) {
  380. var data = _a.data;
  381. return values.push(data);
  382. });
  383. return values;
  384. };
  385. Tree.prototype.min = function () {
  386. if (this._root)
  387. return this.minNode(this._root).key;
  388. return null;
  389. };
  390. Tree.prototype.max = function () {
  391. if (this._root)
  392. return this.maxNode(this._root).key;
  393. return null;
  394. };
  395. Tree.prototype.minNode = function (t) {
  396. if (t === void 0) { t = this._root; }
  397. if (t)
  398. while (t.left)
  399. t = t.left;
  400. return t;
  401. };
  402. Tree.prototype.maxNode = function (t) {
  403. if (t === void 0) { t = this._root; }
  404. if (t)
  405. while (t.right)
  406. t = t.right;
  407. return t;
  408. };
  409. /**
  410. * Returns node at given index
  411. */
  412. Tree.prototype.at = function (index) {
  413. var current = this._root;
  414. var done = false;
  415. var i = 0;
  416. var Q = [];
  417. while (!done) {
  418. if (current) {
  419. Q.push(current);
  420. current = current.left;
  421. }
  422. else {
  423. if (Q.length > 0) {
  424. current = Q.pop();
  425. if (i === index)
  426. return current;
  427. i++;
  428. current = current.right;
  429. }
  430. else
  431. done = true;
  432. }
  433. }
  434. return null;
  435. };
  436. Tree.prototype.next = function (d) {
  437. var root = this._root;
  438. var successor = null;
  439. if (d.right) {
  440. successor = d.right;
  441. while (successor.left)
  442. successor = successor.left;
  443. return successor;
  444. }
  445. var comparator = this._comparator;
  446. while (root) {
  447. var cmp = comparator(d.key, root.key);
  448. if (cmp === 0)
  449. break;
  450. else if (cmp < 0) {
  451. successor = root;
  452. root = root.left;
  453. }
  454. else
  455. root = root.right;
  456. }
  457. return successor;
  458. };
  459. Tree.prototype.prev = function (d) {
  460. var root = this._root;
  461. var predecessor = null;
  462. if (d.left !== null) {
  463. predecessor = d.left;
  464. while (predecessor.right)
  465. predecessor = predecessor.right;
  466. return predecessor;
  467. }
  468. var comparator = this._comparator;
  469. while (root) {
  470. var cmp = comparator(d.key, root.key);
  471. if (cmp === 0)
  472. break;
  473. else if (cmp < 0)
  474. root = root.left;
  475. else {
  476. predecessor = root;
  477. root = root.right;
  478. }
  479. }
  480. return predecessor;
  481. };
  482. Tree.prototype.clear = function () {
  483. this._root = null;
  484. this._size = 0;
  485. return this;
  486. };
  487. Tree.prototype.toList = function () {
  488. return toList(this._root);
  489. };
  490. /**
  491. * Bulk-load items. Both array have to be same size
  492. */
  493. Tree.prototype.load = function (keys, values, presort) {
  494. if (values === void 0) { values = []; }
  495. if (presort === void 0) { presort = false; }
  496. var size = keys.length;
  497. var comparator = this._comparator;
  498. // sort if needed
  499. if (presort)
  500. sort(keys, values, 0, size - 1, comparator);
  501. if (this._root === null) { // empty tree
  502. this._root = loadRecursive(keys, values, 0, size);
  503. this._size = size;
  504. }
  505. else { // that re-builds the whole tree from two in-order traversals
  506. var mergedList = mergeLists(this.toList(), createList(keys, values), comparator);
  507. size = this._size + size;
  508. this._root = sortedListToBST({ head: mergedList }, 0, size);
  509. }
  510. return this;
  511. };
  512. Tree.prototype.isEmpty = function () { return this._root === null; };
  513. Object.defineProperty(Tree.prototype, "size", {
  514. get: function () { return this._size; },
  515. enumerable: true,
  516. configurable: true
  517. });
  518. Object.defineProperty(Tree.prototype, "root", {
  519. get: function () { return this._root; },
  520. enumerable: true,
  521. configurable: true
  522. });
  523. Tree.prototype.toString = function (printNode) {
  524. if (printNode === void 0) { printNode = function (n) { return String(n.key); }; }
  525. var out = [];
  526. printRow(this._root, '', true, function (v) { return out.push(v); }, printNode);
  527. return out.join('');
  528. };
  529. Tree.prototype.update = function (key, newKey, newData) {
  530. var comparator = this._comparator;
  531. var _a = split(key, this._root, comparator), left = _a.left, right = _a.right;
  532. if (comparator(key, newKey) < 0) {
  533. right = insert(newKey, newData, right, comparator);
  534. }
  535. else {
  536. left = insert(newKey, newData, left, comparator);
  537. }
  538. this._root = merge(left, right, comparator);
  539. };
  540. Tree.prototype.split = function (key) {
  541. return split(key, this._root, this._comparator);
  542. };
  543. Tree.prototype[Symbol.iterator] = function () {
  544. var current, Q, done;
  545. return __generator(this, function (_a) {
  546. switch (_a.label) {
  547. case 0:
  548. current = this._root;
  549. Q = [];
  550. done = false;
  551. _a.label = 1;
  552. case 1:
  553. if (!!done) return [3 /*break*/, 6];
  554. if (!(current !== null)) return [3 /*break*/, 2];
  555. Q.push(current);
  556. current = current.left;
  557. return [3 /*break*/, 5];
  558. case 2:
  559. if (!(Q.length !== 0)) return [3 /*break*/, 4];
  560. current = Q.pop();
  561. return [4 /*yield*/, current];
  562. case 3:
  563. _a.sent();
  564. current = current.right;
  565. return [3 /*break*/, 5];
  566. case 4:
  567. done = true;
  568. _a.label = 5;
  569. case 5: return [3 /*break*/, 1];
  570. case 6: return [2 /*return*/];
  571. }
  572. });
  573. };
  574. return Tree;
  575. }());
  576. function loadRecursive(keys, values, start, end) {
  577. var size = end - start;
  578. if (size > 0) {
  579. var middle = start + Math.floor(size / 2);
  580. var key = keys[middle];
  581. var data = values[middle];
  582. var node = new Node(key, data);
  583. node.left = loadRecursive(keys, values, start, middle);
  584. node.right = loadRecursive(keys, values, middle + 1, end);
  585. return node;
  586. }
  587. return null;
  588. }
  589. function createList(keys, values) {
  590. var head = new Node(null, null);
  591. var p = head;
  592. for (var i = 0; i < keys.length; i++) {
  593. p = p.next = new Node(keys[i], values[i]);
  594. }
  595. p.next = null;
  596. return head.next;
  597. }
  598. function toList(root) {
  599. var current = root;
  600. var Q = [];
  601. var done = false;
  602. var head = new Node(null, null);
  603. var p = head;
  604. while (!done) {
  605. if (current) {
  606. Q.push(current);
  607. current = current.left;
  608. }
  609. else {
  610. if (Q.length > 0) {
  611. current = p = p.next = Q.pop();
  612. current = current.right;
  613. }
  614. else
  615. done = true;
  616. }
  617. }
  618. p.next = null; // that'll work even if the tree was empty
  619. return head.next;
  620. }
  621. function sortedListToBST(list, start, end) {
  622. var size = end - start;
  623. if (size > 0) {
  624. var middle = start + Math.floor(size / 2);
  625. var left = sortedListToBST(list, start, middle);
  626. var root = list.head;
  627. root.left = left;
  628. list.head = list.head.next;
  629. root.right = sortedListToBST(list, middle + 1, end);
  630. return root;
  631. }
  632. return null;
  633. }
  634. function mergeLists(l1, l2, compare) {
  635. var head = new Node(null, null); // dummy
  636. var p = head;
  637. var p1 = l1;
  638. var p2 = l2;
  639. while (p1 !== null && p2 !== null) {
  640. if (compare(p1.key, p2.key) < 0) {
  641. p.next = p1;
  642. p1 = p1.next;
  643. }
  644. else {
  645. p.next = p2;
  646. p2 = p2.next;
  647. }
  648. p = p.next;
  649. }
  650. if (p1 !== null) {
  651. p.next = p1;
  652. }
  653. else if (p2 !== null) {
  654. p.next = p2;
  655. }
  656. return head.next;
  657. }
  658. function sort(keys, values, left, right, compare) {
  659. if (left >= right)
  660. return;
  661. var pivot = keys[(left + right) >> 1];
  662. var i = left - 1;
  663. var j = right + 1;
  664. while (true) {
  665. do
  666. i++;
  667. while (compare(keys[i], pivot) < 0);
  668. do
  669. j--;
  670. while (compare(keys[j], pivot) > 0);
  671. if (i >= j)
  672. break;
  673. var tmp = keys[i];
  674. keys[i] = keys[j];
  675. keys[j] = tmp;
  676. tmp = values[i];
  677. values[i] = values[j];
  678. values[j] = tmp;
  679. }
  680. sort(keys, values, left, j, compare);
  681. sort(keys, values, j + 1, right, compare);
  682. }
  683. return Tree;
  684. })));
  685. //# sourceMappingURL=splay.js.map