123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546 |
- import { IllegalStateException, cast_java_lang_IllegalStateException } from '../../../java/lang/IllegalStateException';
- import { MinHeapIterator, cast_de_nrw_schule_svws_core_adt_tree_MinHeapIterator } from '../../../core/adt/tree/MinHeapIterator';
- import { StringBuilder, cast_java_lang_StringBuilder } from '../../../java/lang/StringBuilder';
- import { JavaString, cast_java_lang_String } from '../../../java/lang/JavaString';
- import { System, cast_java_lang_System } from '../../../java/lang/System';
- import { Comparator, cast_java_util_Comparator } from '../../../java/util/Comparator';
- import { JavaInteger, cast_java_lang_Integer } from '../../../java/lang/JavaInteger';
- import { NullPointerException, cast_java_lang_NullPointerException } from '../../../java/lang/NullPointerException';
- import { JavaIterator, cast_java_util_Iterator } from '../../../java/util/JavaIterator';
- import { Collection, cast_java_util_Collection } from '../../../java/util/Collection';
- import { Cloneable, cast_java_lang_Cloneable } from '../../../java/lang/Cloneable';
- import { JavaObject, cast_java_lang_Object } from '../../../java/lang/JavaObject';
- import { Arrays, cast_java_util_Arrays } from '../../../java/util/Arrays';
- import { Queue, cast_java_util_Queue } from '../../../java/util/Queue';
- import { IllegalArgumentException, cast_java_lang_IllegalArgumentException } from '../../../java/lang/IllegalArgumentException';
- import { NoSuchElementException, cast_java_util_NoSuchElementException } from '../../../java/util/NoSuchElementException';
- import { CloneNotSupportedException, cast_java_lang_CloneNotSupportedException } from '../../../java/lang/CloneNotSupportedException';
- export class MinHeap<T> extends JavaObject implements Queue<T>, Cloneable {
- private _size : number = 0;
- private _nodes : Array<T | null> = Array(0).fill(null);
- private readonly _comparator : Comparator<T>;
- private readonly _initialCapacity : number;
- protected _modCount : number = 0;
- /**
- * Erzeugt einen neuen Minimum-Heap mit dem übergebenen {@link Comparator} und
- * der übergebenen initialen Kapazität.
- *
- * @param comparator das Objekt zum Vergleich von zwei Objekten des Typ T
- * @param initialCapacity die initiale Kapazität des Baums
- */
- public constructor(comparator : Comparator<T>, initialCapacity : number);
- /**
- * Erzeugt einen neuen Minimum-Heap mit dem übergebenen {@link Comparator} und
- * einer initialen Kapazität von 63.
- *
- * @param comparator das Objekt zum Vergleich von zwei Objekten des Typ T
- */
- public constructor(comparator : Comparator<T>);
- /**
- * Erstellt eine Kopie des als Parameter übergebenen Heaps.
- *
- * @param original Das zu kopierende Original
- */
- public constructor(original : MinHeap<T>);
- /**
- * Implementation for method overloads of 'constructor'
- */
- public constructor(__param0 : Comparator<T> | MinHeap<T>, __param1? : number) {
- super();
- 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")) {
- let comparator : Comparator<T> = cast_java_util_Comparator(__param0);
- let initialCapacity : number = __param1 as number;
- if (initialCapacity <= 0)
- throw new IllegalArgumentException("Die initiale Kapazität muss größer als 0 sein.")
- this._comparator = comparator;
- this._initialCapacity = initialCapacity;
- this._modCount = 0;
- } 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")) {
- let comparator : Comparator<T> = cast_java_util_Comparator(__param0);
- this._comparator = comparator;
- this._initialCapacity = 63;
- this._modCount = 0;
- } else if (((typeof __param0 !== "undefined") && ((__param0 instanceof JavaObject) && (__param0.isTranspiledInstanceOf('de.nrw.schule.svws.core.adt.tree.MinHeap'))) || (__param0 === null)) && (typeof __param1 === "undefined")) {
- let original : MinHeap<T> = cast_de_nrw_schule_svws_core_adt_tree_MinHeap(__param0);
- this._comparator = original._comparator;
- this._initialCapacity = original._initialCapacity;
- this._nodes = Arrays.copyOf(original._nodes, original._nodes.length);
- this._size = original._size;
- this._modCount = original._modCount;
- } else throw new Error('invalid method overload');
- }
- public add(e : T) : boolean {
- if (e === null)
- return false;
- if (this._nodes.length === 0)
- this._nodes = this.newArray(e, this._initialCapacity);
- if (this._size === this._nodes.length)
- this.grow();
- this._nodes[this._size] = e;
- this.heapifyUp(this._size++);
- this._modCount++;
- return true;
- }
- public element() : T {
- if ((this._size === 0) || (this._nodes[0] === null))
- throw new NoSuchElementException()
- return this._nodes[0];
- }
- public offer(e : T) : boolean {
- return this.add(e);
- }
- public peek() : T | null {
- return this._nodes.length === 0 ? null : this._nodes[0];
- }
- public poll() : T | null {
- if (this._size === 0)
- return null;
- let elem : T | null = this._nodes[0];
- this._nodes[0] = this._nodes[--this._size];
- this._nodes[this._size] = null;
- this.heapifyDown(0);
- this._modCount++;
- return elem;
- }
- public remove() : T;
- public remove(o : unknown | null) : boolean;
- /**
- * Implementation for method overloads of 'remove'
- */
- public remove(__param0? : null | unknown) : T | boolean {
- if ((typeof __param0 === "undefined")) {
- let result : T | null = this.poll();
- if (result === null)
- throw new NoSuchElementException()
- return result;
- } else if (((typeof __param0 !== "undefined") && ((__param0 instanceof Object) || ((__param0 instanceof JavaObject) && (__param0.isTranspiledInstanceOf('java.lang.Object')))) || (__param0 === null))) {
- let o : unknown | null = (__param0 instanceof JavaObject) ? cast_java_lang_Object(__param0) : __param0;
- if (o === null)
- return false;
- let index : number = this.findIndex(o);
- if (index === -1)
- return false;
- this._size--;
- this._modCount++;
- if (index === this._size)
- return true;
- this._nodes[index] = this._nodes[this._size];
- this._nodes[this._size] = null;
- this.heapifyUp(index);
- this.heapifyDown(index);
- return true;
- } else throw new Error('invalid method overload');
- }
- public size() : number {
- return this._size;
- }
- public isEmpty() : boolean {
- return this._size === 0;
- }
- public contains(o : unknown | null) : boolean {
- if (o === null)
- return false;
- for (let i : number = 0; i < this._size; i++){
- if (JavaObject.equalsTranspiler(this._nodes[i], (o)))
- return true;
- }
- return false;
- }
- public containsAll(c : Collection<unknown> | null) : boolean {
- if (c === null)
- return true;
- if (this as unknown === c as unknown)
- return true;
- for (let o of c)
- if (!this.contains(o))
- return false;
- return true;
- }
- public addAll(c : Collection<T> | null) : boolean {
- if (c === null)
- return false;
- if (this as unknown === c as unknown) {
- if (this._size === 0)
- return false;
- let tmp : Array<T | null> = Arrays.copyOf(this._nodes, this._size);
- for (let t of tmp)
- if (t !== null)
- this.add(t);
- return true;
- }
- let result : boolean = false;
- for (let t of c) {
- if (this.add(t))
- result = true;
- }
- return result;
- }
- public removeAll(c : Collection<unknown> | null) : boolean {
- if (c === null)
- return false;
- if (this as unknown === c as unknown) {
- if (this.size() === 0)
- return false;
- this.clear();
- return true;
- }
- let result : boolean = false;
- for (let o of c) {
- if (this.remove(o)) {
- result = true;
- while (this.remove(o)) ;
- }
- }
- return result;
- }
- public retainAll(c : Collection<unknown> | null) : boolean {
- if (this._size === 0)
- return false;
- if (c === null) {
- this.clear();
- return true;
- }
- if (this as unknown === c as unknown)
- return false;
- let tmp : Array<T | null> = this.newArray(this._nodes[0], this._nodes.length);
- if (tmp === null)
- return false;
- let i : number = 0;
- let elem : T | null;
- let changed : boolean = false;
- while ((elem = this.poll()) !== null) {
- if (c.contains(elem))
- tmp[i++] = elem; else
- changed = true;
- }
- this._nodes = tmp;
- this._size = i;
- this._modCount++;
- return changed;
- }
- public clear() : void {
- this._nodes = Array(0).fill(null);
- this._size = 0;
- this._modCount++;
- }
- public toArray() : Array<unknown>;
- public toArray<U>(a : Array<U>) : Array<U>;
- /**
- * Implementation for method overloads of 'toArray'
- */
- public toArray<U>(__param0? : Array<U>) : Array<U> | Array<unknown> {
- if ((typeof __param0 === "undefined")) {
- return this.copyNodes();
- } else if (((typeof __param0 !== "undefined") && Array.isArray(__param0))) {
- let a : Array<U> = __param0;
- if (a.length < this._size)
- return this.copyNodes();
- System.arraycopy(this._nodes, 0, a, 0, this._size);
- Arrays.fill(a, this._size, a.length, null);
- return a;
- } else throw new Error('invalid method overload');
- }
- public iterator() : JavaIterator<T> {
- return new MinHeapIterator(this._nodes, this);
- }
- public clone() : unknown {
- return new MinHeap(this);
- }
- /**
- * Gibt den {@link Comparator} des Minimum Heaps zurück.
- *
- * @return der Comparator
- */
- public comparator() : Comparator<T> {
- return this._comparator;
- }
- /**
- * Gibt die aktuelle Kapazität des Arrays zurück.
- *
- * @return die aktuelle Kapazität des Arrays zurück
- */
- public capacity() : number {
- return (this._nodes.length === 0) ? this._initialCapacity : this._nodes.length;
- }
- /**
- * Gibt den Inhalt des Minimum Heaps in einem sortierten Array zurück.
- *
- * @return ein sortiertes Array mit den Elementen des Minimum Heaps.
- */
- public toSortedArray() : Array<T> {
- if (this._size === 0)
- return Array(0).fill(null);
- let copy : MinHeap<T> = new MinHeap(this);
- let tmp : Array<T> = this.newArray(this._nodes[0], this._size);
- let current : T | null;
- let i : number = 0;
- while ((current = copy.poll()) !== null)
- tmp[i++] = current;
- return tmp;
- }
- /**
- * Gibt den Inhalt des Heaps als Array-Repräsentation aus.
- *
- * @return der Inhalt des Heaps
- */
- public toString() : String {
- let sb : StringBuilder = new StringBuilder();
- for (let i : number = 0; i < this._size; i++){
- sb.append(this._nodes[i]);
- if (i !== this._size - 1)
- sb.append(", ");
- }
- return sb.toString();
- }
- /**
- * Ermittelt eine Hash-Code für dieses Objekt basierend auf den gespeicherten
- * Daten im Heap (die konkrete Ordnung des Baumes wird nicht unterschieden).
- *
- * @return der Hashcode des Minimum Heaps
- */
- public hashCode() : number {
- return Arrays.deepHashCode(this.toSortedArray());
- }
- /**
- * Prüft, ob das übergebene Objekt ein Minimum-Heap ist, der
- * die gleichen Elemente mit der gleichen Ordnung beinhaltet.
- *
- * @param obj das zu vergleichende Objekt
- */
- public equals(obj : unknown | null) : boolean {
- if (this as unknown === obj as unknown)
- return true;
- if (obj === null)
- return false;
- if (((obj instanceof JavaObject) && (obj.isTranspiledInstanceOf('de.nrw.schule.svws.core.adt.tree.MinHeap')))) {
- let other : MinHeap<unknown> | null = cast_de_nrw_schule_svws_core_adt_tree_MinHeap(obj);
- return Arrays.deepEquals(this.toSortedArray(), other.toSortedArray());
- }
- return false;
- }
- /**
- * Liefert zum Index i den Index des Elter zurück.
- *
- * @param i
- *
- * @return den Index des Elter
- */
- private static getParentIndex(i : number) : number {
- return (i <= 0) ? -1 : Math.trunc((i - 1) / 2);
- }
- /**
- * Liefert zum Index i den Index des linken Kindes zurück.
- *
- * @param i
- *
- * @return den Index des linken Kindes
- */
- private static getLeftChildIndex(i : number) : number {
- return 2 * i + 1;
- }
- /**
- * Liefert zum Index i den Index des rechten Kindes zurück.
- *
- * @param i
- *
- * @return den Index des rechten Kindes
- */
- private static getRightChildIndex(i : number) : number {
- return 2 * i + 2;
- }
- /**
- * Tauscht die Elemente an den Stellen i und j im Array
- *
- * @param i
- * @param j
- */
- private swap(i : number, j : number) : void {
- let elem : T | null = this._nodes[i];
- this._nodes[i] = this._nodes[j];
- this._nodes[j] = elem;
- }
- /**
- * Stellt die Minimum Heap Eigenschaft vom Index i aus im Baum abwärts her.
- *
- * @param i ab diesem Index wird im Baum abwärts geprüft.
- */
- private heapifyDown(i : number) : void {
- let left : number = MinHeap.getLeftChildIndex(i);
- let right : number = MinHeap.getRightChildIndex(i);
- if (left >= this._size)
- return;
- let child : number = right;
- if (right === this._size) {
- child = left;
- } else {
- let nodeLeft : T | null = this._nodes[left];
- let nodeRight : T | null = this._nodes[right];
- if ((nodeLeft === null) || (nodeRight === null))
- return;
- if (this._comparator.compare(nodeLeft, nodeRight) < 0)
- child = left;
- }
- let nodeCurrent : T | null = this._nodes[i];
- let nodeChild : T | null = this._nodes[child];
- if ((nodeCurrent === null) || (nodeChild === null))
- throw new NullPointerException()
- if (this._comparator.compare(nodeCurrent, nodeChild) <= 0)
- return;
- this.swap(i, child);
- this.heapifyDown(child);
- }
- /**
- * Stellt die Minimum-Heap-Eigenschaft des Arrays ab Position i aufwärts wieder her.
- *
- * @param i ab diesem Index wird überprüft
- */
- private heapifyUp(i : number) : void {
- let parentIndex : number = MinHeap.getParentIndex(i);
- if (parentIndex < 0)
- return;
- let nodeCurrent : T | null = this._nodes[i];
- let nodeParent : T | null = this._nodes[parentIndex];
- if ((nodeCurrent === null) || (nodeParent === null) || (this._comparator.compare(nodeCurrent, nodeParent) >= 0))
- return;
- this.swap(i, parentIndex);
- this.heapifyUp(parentIndex);
- }
- /**
- * Erstellt ein neues Array vom Typ T mit der angegebenen Länge.
- *
- * @param elem Ein Element vom Typ T, welches als Vorlage für die Elemente des Arrays dient
- * @param length die Länge des neuen Arrays
- *
- * @return das neue Array
- */
- private newArray(elem : T | null, length : number) : Array<T> {
- if (elem === null)
- return Array(length).fill(null);
- return Array(length).fill(null);
- }
- /**
- * Erzeugt eine Kopie des internen Arrays _nodes.
- *
- * @return die Kopie des _nodes-Array.
- */
- private copyNodes() : Array<T> {
- let result : Array<T> = this.newArray(this._size <= 0 ? null : this._nodes[0], this._size);
- System.arraycopy(this._nodes, 0, result, 0, this._size);
- return result;
- }
- /**
- * Lässt den dem Baum zu Grunde liegenden Baum wachsen. Verdoppelt die Menge der Elemente, die im Heap
- * gespeichert werden können.
- *
- * Falls der Heap durch das Wachsen auf mehr als {@link Integer.MAX_VALUE} Elemente ansteigen würde,
- * wird eine IllegalStateException geworfen.
- *
- * @throws IllegalStateException
- */
- private grow() : void {
- if (this._nodes.length === Number.MAX_VALUE)
- throw new IllegalStateException("Der Minimum-Heap kann nicht mehr als " + Number.MAX_VALUE + " Elemente beinhalten.")
- let newLength : number = this._nodes.length * 2 + 1;
- if (newLength < 0)
- newLength = Number.MAX_VALUE;
- let tmp : Array<T> = this.newArray(this._nodes[0], newLength);
- System.arraycopy(this._nodes, 0, tmp, 0, this._size);
- this._nodes = tmp;
- }
- /**
- * Findet den Index an dem das Element t im dem dem Heap zu Grunde liegendem Array gespeichert ist.
- * Gibt -1 zurück, falls das Element nicht vorhanden ist.
- *
- * @param t zu diesem Element soll der Index gefunden werden
- *
- * @return der Index, falls das Element enthalten ist, ansonsten -1
- */
- private findIndex(obj : unknown | null) : number {
- if (obj === null)
- return -1;
- for (let i : number = 0; i < this._size; i++){
- if (JavaObject.equalsTranspiler(this._nodes[i], (obj)))
- return i;
- }
- return -1;
- }
- /**
- * Gibt die Anzahl der Operationen zurück, die diese Datenstruktur
- * verändert haben.
- *
- * @return die Anzahl der Operationen
- */
- getModCount() : number {
- return this._modCount;
- }
- isTranspiledInstanceOf(name : string): boolean {
- return ['java.lang.Cloneable', 'de.nrw.schule.svws.core.adt.tree.MinHeap', 'java.util.Collection', 'java.util.Queue', 'java.lang.Iterable'].includes(name);
- }
- public [Symbol.iterator](): Iterator<T> {
- let iter : JavaIterator<T> = this.iterator();
- const result : Iterator<T> = {
- next() : IteratorResult<T> {
- if (iter.hasNext())
- return { value : iter.next(), done : false };
- return { value : null, done : true };
- }
- };
- return result;
- }
- }
- export function cast_de_nrw_schule_svws_core_adt_tree_MinHeap<T>(obj : unknown) : MinHeap<T> {
- return obj as MinHeap<T>;
- }
|