MinHeap.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.cast_de_nrw_schule_svws_core_adt_tree_MinHeap = exports.MinHeap = void 0;
  4. const IllegalStateException_1 = require("../../../java/lang/IllegalStateException");
  5. const MinHeapIterator_1 = require("../../../core/adt/tree/MinHeapIterator");
  6. const StringBuilder_1 = require("../../../java/lang/StringBuilder");
  7. const System_1 = require("../../../java/lang/System");
  8. const Comparator_1 = require("../../../java/util/Comparator");
  9. const NullPointerException_1 = require("../../../java/lang/NullPointerException");
  10. const JavaObject_1 = require("../../../java/lang/JavaObject");
  11. const Arrays_1 = require("../../../java/util/Arrays");
  12. const IllegalArgumentException_1 = require("../../../java/lang/IllegalArgumentException");
  13. const NoSuchElementException_1 = require("../../../java/util/NoSuchElementException");
  14. class MinHeap extends JavaObject_1.JavaObject {
  15. _size = 0;
  16. _nodes = Array(0).fill(null);
  17. _comparator;
  18. _initialCapacity;
  19. _modCount = 0;
  20. /**
  21. * Implementation for method overloads of 'constructor'
  22. */
  23. constructor(__param0, __param1) {
  24. super();
  25. if (((typeof __param0 !== "undefined") && ((typeof __param0 !== 'undefined') && (__param0 instanceof Object) && (__param0 !== null) && ('compare' in __param0) && (typeof __param0.compare === 'function')) || (__param0 === null)) && ((typeof __param1 !== "undefined") && typeof __param1 === "number")) {
  26. let comparator = (0, Comparator_1.cast_java_util_Comparator)(__param0);
  27. let initialCapacity = __param1;
  28. if (initialCapacity <= 0)
  29. throw new IllegalArgumentException_1.IllegalArgumentException("Die initiale Kapazität muss größer als 0 sein.");
  30. this._comparator = comparator;
  31. this._initialCapacity = initialCapacity;
  32. this._modCount = 0;
  33. }
  34. else if (((typeof __param0 !== "undefined") && ((typeof __param0 !== 'undefined') && (__param0 instanceof Object) && (__param0 !== null) && ('compare' in __param0) && (typeof __param0.compare === 'function')) || (__param0 === null)) && (typeof __param1 === "undefined")) {
  35. let comparator = (0, Comparator_1.cast_java_util_Comparator)(__param0);
  36. this._comparator = comparator;
  37. this._initialCapacity = 63;
  38. this._modCount = 0;
  39. }
  40. else if (((typeof __param0 !== "undefined") && ((__param0 instanceof JavaObject_1.JavaObject) && (__param0.isTranspiledInstanceOf('de.nrw.schule.svws.core.adt.tree.MinHeap'))) || (__param0 === null)) && (typeof __param1 === "undefined")) {
  41. let original = cast_de_nrw_schule_svws_core_adt_tree_MinHeap(__param0);
  42. this._comparator = original._comparator;
  43. this._initialCapacity = original._initialCapacity;
  44. this._nodes = Arrays_1.Arrays.copyOf(original._nodes, original._nodes.length);
  45. this._size = original._size;
  46. this._modCount = original._modCount;
  47. }
  48. else
  49. throw new Error('invalid method overload');
  50. }
  51. add(e) {
  52. if (e === null)
  53. return false;
  54. if (this._nodes.length === 0)
  55. this._nodes = this.newArray(e, this._initialCapacity);
  56. if (this._size === this._nodes.length)
  57. this.grow();
  58. this._nodes[this._size] = e;
  59. this.heapifyUp(this._size++);
  60. this._modCount++;
  61. return true;
  62. }
  63. element() {
  64. if ((this._size === 0) || (this._nodes[0] === null))
  65. throw new NoSuchElementException_1.NoSuchElementException();
  66. return this._nodes[0];
  67. }
  68. offer(e) {
  69. return this.add(e);
  70. }
  71. peek() {
  72. return this._nodes.length === 0 ? null : this._nodes[0];
  73. }
  74. poll() {
  75. if (this._size === 0)
  76. return null;
  77. let elem = this._nodes[0];
  78. this._nodes[0] = this._nodes[--this._size];
  79. this._nodes[this._size] = null;
  80. this.heapifyDown(0);
  81. this._modCount++;
  82. return elem;
  83. }
  84. /**
  85. * Implementation for method overloads of 'remove'
  86. */
  87. remove(__param0) {
  88. if ((typeof __param0 === "undefined")) {
  89. let result = this.poll();
  90. if (result === null)
  91. throw new NoSuchElementException_1.NoSuchElementException();
  92. return result;
  93. }
  94. else if (((typeof __param0 !== "undefined") && ((__param0 instanceof Object) || ((__param0 instanceof JavaObject_1.JavaObject) && (__param0.isTranspiledInstanceOf('java.lang.Object')))) || (__param0 === null))) {
  95. let o = (__param0 instanceof JavaObject_1.JavaObject) ? (0, JavaObject_1.cast_java_lang_Object)(__param0) : __param0;
  96. if (o === null)
  97. return false;
  98. let index = this.findIndex(o);
  99. if (index === -1)
  100. return false;
  101. this._size--;
  102. this._modCount++;
  103. if (index === this._size)
  104. return true;
  105. this._nodes[index] = this._nodes[this._size];
  106. this._nodes[this._size] = null;
  107. this.heapifyUp(index);
  108. this.heapifyDown(index);
  109. return true;
  110. }
  111. else
  112. throw new Error('invalid method overload');
  113. }
  114. size() {
  115. return this._size;
  116. }
  117. isEmpty() {
  118. return this._size === 0;
  119. }
  120. contains(o) {
  121. if (o === null)
  122. return false;
  123. for (let i = 0; i < this._size; i++) {
  124. if (JavaObject_1.JavaObject.equalsTranspiler(this._nodes[i], (o)))
  125. return true;
  126. }
  127. return false;
  128. }
  129. containsAll(c) {
  130. if (c === null)
  131. return true;
  132. if (this === c)
  133. return true;
  134. for (let o of c)
  135. if (!this.contains(o))
  136. return false;
  137. return true;
  138. }
  139. addAll(c) {
  140. if (c === null)
  141. return false;
  142. if (this === c) {
  143. if (this._size === 0)
  144. return false;
  145. let tmp = Arrays_1.Arrays.copyOf(this._nodes, this._size);
  146. for (let t of tmp)
  147. if (t !== null)
  148. this.add(t);
  149. return true;
  150. }
  151. let result = false;
  152. for (let t of c) {
  153. if (this.add(t))
  154. result = true;
  155. }
  156. return result;
  157. }
  158. removeAll(c) {
  159. if (c === null)
  160. return false;
  161. if (this === c) {
  162. if (this.size() === 0)
  163. return false;
  164. this.clear();
  165. return true;
  166. }
  167. let result = false;
  168. for (let o of c) {
  169. if (this.remove(o)) {
  170. result = true;
  171. while (this.remove(o))
  172. ;
  173. }
  174. }
  175. return result;
  176. }
  177. retainAll(c) {
  178. if (this._size === 0)
  179. return false;
  180. if (c === null) {
  181. this.clear();
  182. return true;
  183. }
  184. if (this === c)
  185. return false;
  186. let tmp = this.newArray(this._nodes[0], this._nodes.length);
  187. if (tmp === null)
  188. return false;
  189. let i = 0;
  190. let elem;
  191. let changed = false;
  192. while ((elem = this.poll()) !== null) {
  193. if (c.contains(elem))
  194. tmp[i++] = elem;
  195. else
  196. changed = true;
  197. }
  198. this._nodes = tmp;
  199. this._size = i;
  200. this._modCount++;
  201. return changed;
  202. }
  203. clear() {
  204. this._nodes = Array(0).fill(null);
  205. this._size = 0;
  206. this._modCount++;
  207. }
  208. /**
  209. * Implementation for method overloads of 'toArray'
  210. */
  211. toArray(__param0) {
  212. if ((typeof __param0 === "undefined")) {
  213. return this.copyNodes();
  214. }
  215. else if (((typeof __param0 !== "undefined") && Array.isArray(__param0))) {
  216. let a = __param0;
  217. if (a.length < this._size)
  218. return this.copyNodes();
  219. System_1.System.arraycopy(this._nodes, 0, a, 0, this._size);
  220. Arrays_1.Arrays.fill(a, this._size, a.length, null);
  221. return a;
  222. }
  223. else
  224. throw new Error('invalid method overload');
  225. }
  226. iterator() {
  227. return new MinHeapIterator_1.MinHeapIterator(this._nodes, this);
  228. }
  229. clone() {
  230. return new MinHeap(this);
  231. }
  232. /**
  233. * Gibt den {@link Comparator} des Minimum Heaps zurück.
  234. *
  235. * @return der Comparator
  236. */
  237. comparator() {
  238. return this._comparator;
  239. }
  240. /**
  241. * Gibt die aktuelle Kapazität des Arrays zurück.
  242. *
  243. * @return die aktuelle Kapazität des Arrays zurück
  244. */
  245. capacity() {
  246. return (this._nodes.length === 0) ? this._initialCapacity : this._nodes.length;
  247. }
  248. /**
  249. * Gibt den Inhalt des Minimum Heaps in einem sortierten Array zurück.
  250. *
  251. * @return ein sortiertes Array mit den Elementen des Minimum Heaps.
  252. */
  253. toSortedArray() {
  254. if (this._size === 0)
  255. return Array(0).fill(null);
  256. let copy = new MinHeap(this);
  257. let tmp = this.newArray(this._nodes[0], this._size);
  258. let current;
  259. let i = 0;
  260. while ((current = copy.poll()) !== null)
  261. tmp[i++] = current;
  262. return tmp;
  263. }
  264. /**
  265. * Gibt den Inhalt des Heaps als Array-Repräsentation aus.
  266. *
  267. * @return der Inhalt des Heaps
  268. */
  269. toString() {
  270. let sb = new StringBuilder_1.StringBuilder();
  271. for (let i = 0; i < this._size; i++) {
  272. sb.append(this._nodes[i]);
  273. if (i !== this._size - 1)
  274. sb.append(", ");
  275. }
  276. return sb.toString();
  277. }
  278. /**
  279. * Ermittelt eine Hash-Code für dieses Objekt basierend auf den gespeicherten
  280. * Daten im Heap (die konkrete Ordnung des Baumes wird nicht unterschieden).
  281. *
  282. * @return der Hashcode des Minimum Heaps
  283. */
  284. hashCode() {
  285. return Arrays_1.Arrays.deepHashCode(this.toSortedArray());
  286. }
  287. /**
  288. * Prüft, ob das übergebene Objekt ein Minimum-Heap ist, der
  289. * die gleichen Elemente mit der gleichen Ordnung beinhaltet.
  290. *
  291. * @param obj das zu vergleichende Objekt
  292. */
  293. equals(obj) {
  294. if (this === obj)
  295. return true;
  296. if (obj === null)
  297. return false;
  298. if (((obj instanceof JavaObject_1.JavaObject) && (obj.isTranspiledInstanceOf('de.nrw.schule.svws.core.adt.tree.MinHeap')))) {
  299. let other = cast_de_nrw_schule_svws_core_adt_tree_MinHeap(obj);
  300. return Arrays_1.Arrays.deepEquals(this.toSortedArray(), other.toSortedArray());
  301. }
  302. return false;
  303. }
  304. /**
  305. * Liefert zum Index i den Index des Elter zurück.
  306. *
  307. * @param i
  308. *
  309. * @return den Index des Elter
  310. */
  311. static getParentIndex(i) {
  312. return (i <= 0) ? -1 : Math.trunc((i - 1) / 2);
  313. }
  314. /**
  315. * Liefert zum Index i den Index des linken Kindes zurück.
  316. *
  317. * @param i
  318. *
  319. * @return den Index des linken Kindes
  320. */
  321. static getLeftChildIndex(i) {
  322. return 2 * i + 1;
  323. }
  324. /**
  325. * Liefert zum Index i den Index des rechten Kindes zurück.
  326. *
  327. * @param i
  328. *
  329. * @return den Index des rechten Kindes
  330. */
  331. static getRightChildIndex(i) {
  332. return 2 * i + 2;
  333. }
  334. /**
  335. * Tauscht die Elemente an den Stellen i und j im Array
  336. *
  337. * @param i
  338. * @param j
  339. */
  340. swap(i, j) {
  341. let elem = this._nodes[i];
  342. this._nodes[i] = this._nodes[j];
  343. this._nodes[j] = elem;
  344. }
  345. /**
  346. * Stellt die Minimum Heap Eigenschaft vom Index i aus im Baum abwärts her.
  347. *
  348. * @param i ab diesem Index wird im Baum abwärts geprüft.
  349. */
  350. heapifyDown(i) {
  351. let left = MinHeap.getLeftChildIndex(i);
  352. let right = MinHeap.getRightChildIndex(i);
  353. if (left >= this._size)
  354. return;
  355. let child = right;
  356. if (right === this._size) {
  357. child = left;
  358. }
  359. else {
  360. let nodeLeft = this._nodes[left];
  361. let nodeRight = this._nodes[right];
  362. if ((nodeLeft === null) || (nodeRight === null))
  363. return;
  364. if (this._comparator.compare(nodeLeft, nodeRight) < 0)
  365. child = left;
  366. }
  367. let nodeCurrent = this._nodes[i];
  368. let nodeChild = this._nodes[child];
  369. if ((nodeCurrent === null) || (nodeChild === null))
  370. throw new NullPointerException_1.NullPointerException();
  371. if (this._comparator.compare(nodeCurrent, nodeChild) <= 0)
  372. return;
  373. this.swap(i, child);
  374. this.heapifyDown(child);
  375. }
  376. /**
  377. * Stellt die Minimum-Heap-Eigenschaft des Arrays ab Position i aufwärts wieder her.
  378. *
  379. * @param i ab diesem Index wird überprüft
  380. */
  381. heapifyUp(i) {
  382. let parentIndex = MinHeap.getParentIndex(i);
  383. if (parentIndex < 0)
  384. return;
  385. let nodeCurrent = this._nodes[i];
  386. let nodeParent = this._nodes[parentIndex];
  387. if ((nodeCurrent === null) || (nodeParent === null) || (this._comparator.compare(nodeCurrent, nodeParent) >= 0))
  388. return;
  389. this.swap(i, parentIndex);
  390. this.heapifyUp(parentIndex);
  391. }
  392. /**
  393. * Erstellt ein neues Array vom Typ T mit der angegebenen Länge.
  394. *
  395. * @param elem Ein Element vom Typ T, welches als Vorlage für die Elemente des Arrays dient
  396. * @param length die Länge des neuen Arrays
  397. *
  398. * @return das neue Array
  399. */
  400. newArray(elem, length) {
  401. if (elem === null)
  402. return Array(length).fill(null);
  403. return Array(length).fill(null);
  404. }
  405. /**
  406. * Erzeugt eine Kopie des internen Arrays _nodes.
  407. *
  408. * @return die Kopie des _nodes-Array.
  409. */
  410. copyNodes() {
  411. let result = this.newArray(this._size <= 0 ? null : this._nodes[0], this._size);
  412. System_1.System.arraycopy(this._nodes, 0, result, 0, this._size);
  413. return result;
  414. }
  415. /**
  416. * Lässt den dem Baum zu Grunde liegenden Baum wachsen. Verdoppelt die Menge der Elemente, die im Heap
  417. * gespeichert werden können.
  418. *
  419. * Falls der Heap durch das Wachsen auf mehr als {@link Integer.MAX_VALUE} Elemente ansteigen würde,
  420. * wird eine IllegalStateException geworfen.
  421. *
  422. * @throws IllegalStateException
  423. */
  424. grow() {
  425. if (this._nodes.length === Number.MAX_VALUE)
  426. throw new IllegalStateException_1.IllegalStateException("Der Minimum-Heap kann nicht mehr als " + Number.MAX_VALUE + " Elemente beinhalten.");
  427. let newLength = this._nodes.length * 2 + 1;
  428. if (newLength < 0)
  429. newLength = Number.MAX_VALUE;
  430. let tmp = this.newArray(this._nodes[0], newLength);
  431. System_1.System.arraycopy(this._nodes, 0, tmp, 0, this._size);
  432. this._nodes = tmp;
  433. }
  434. /**
  435. * Findet den Index an dem das Element t im dem dem Heap zu Grunde liegendem Array gespeichert ist.
  436. * Gibt -1 zurück, falls das Element nicht vorhanden ist.
  437. *
  438. * @param t zu diesem Element soll der Index gefunden werden
  439. *
  440. * @return der Index, falls das Element enthalten ist, ansonsten -1
  441. */
  442. findIndex(obj) {
  443. if (obj === null)
  444. return -1;
  445. for (let i = 0; i < this._size; i++) {
  446. if (JavaObject_1.JavaObject.equalsTranspiler(this._nodes[i], (obj)))
  447. return i;
  448. }
  449. return -1;
  450. }
  451. /**
  452. * Gibt die Anzahl der Operationen zurück, die diese Datenstruktur
  453. * verändert haben.
  454. *
  455. * @return die Anzahl der Operationen
  456. */
  457. getModCount() {
  458. return this._modCount;
  459. }
  460. isTranspiledInstanceOf(name) {
  461. return ['java.lang.Cloneable', 'de.nrw.schule.svws.core.adt.tree.MinHeap', 'java.util.Collection', 'java.util.Queue', 'java.lang.Iterable'].includes(name);
  462. }
  463. [Symbol.iterator]() {
  464. let iter = this.iterator();
  465. const result = {
  466. next() {
  467. if (iter.hasNext())
  468. return { value: iter.next(), done: false };
  469. return { value: null, done: true };
  470. }
  471. };
  472. return result;
  473. }
  474. }
  475. exports.MinHeap = MinHeap;
  476. function cast_de_nrw_schule_svws_core_adt_tree_MinHeap(obj) {
  477. return obj;
  478. }
  479. exports.cast_de_nrw_schule_svws_core_adt_tree_MinHeap = cast_de_nrw_schule_svws_core_adt_tree_MinHeap;
  480. //# sourceMappingURL=MinHeap.js.map