krahets/hello-algo · error · RangeError

Heap is empty.

Error message

Heap is empty.

What it means

Thrown by pop() on a max-heap when the heap contains no elements (isEmpty() is true). It prevents swapping/sifting on an undefined root and returning undefined as a number. Thrown as a RangeError to signal an empty-collection access.

Source

Thrown at ru/codes/typescript/chapter_heap/my_heap.ts:84

    /* Начиная с узла i, выполнить просеивание снизу вверх */
    private siftUp(i: number): void {
        while (true) {
            // Получение родительского узла для узла i
            const p = this.parent(i);
            // Завершить heapify, когда «корневой узел уже пройден» или «узел не требует исправления»
            if (p < 0 || this.maxHeap[i] <= this.maxHeap[p]) break;
            // Поменять два узла местами
            this.swap(i, p);
            // Циклическое просеивание вверх
            i = p;
        }
    }

    /* Извлечение элемента из кучи */
    public pop(): number {
        // Обработка пустого случая
        if (this.isEmpty()) throw new RangeError('Heap is empty.');
        // Поменять корневой узел с самым правым листом местами (поменять первый и последний элементы)
        this.swap(0, this.size() - 1);
        // Удаление узла
        const val = this.maxHeap.pop();
        // Просеивание сверху вниз
        this.siftDown(0);
        // Вернуть элемент с вершины кучи
        return val;
    }

    /* Начиная с узла i, выполнить просеивание сверху вниз */
    private siftDown(i: number): void {
        while (true) {
            // Определить узел с максимальным значением среди i, l и r и обозначить его как ma
            const l = this.left(i),
                r = this.right(i);
            let ma = i;
            if (l < this.size() && this.maxHeap[l] > this.maxHeap[ma]) ma = l;

View on GitHub (pinned to 69932aed18)

Solutions

  1. Always check heap.isEmpty() before calling pop().
  2. Drive the drain loop with while (!heap.isEmpty()) { ... heap.pop() ... }.
  3. If pop must be called defensively, wrap it in try/catch and treat empty as a sentinel.
  4. Ensure inserts (push) precede pops by verifying the count logic.

Example fix

// before
while (true) {
    const v = heap.pop(); // throws when drained
}

// after
while (!heap.isEmpty()) {
    const v = heap.pop();
}
Defensive patterns

Strategy: validation

Validate before calling

if (!heap.isEmpty()) {
    const val = heap.pop();
}

Try / catch

try {
    const val = heap.pop();
} catch (e) {
    if (e instanceof RangeError && e.message === 'Heap is empty.') {
        // handle empty heap
    } else throw e;
}

Prevention

When it happens

Trigger: Calling pop() more times than elements were pushed; calling pop() immediately after construction with no inserts; draining the heap in a loop without a termination check.

Common situations: Priority-queue consumers that pop in a while(true) loop and forget the empty check; using the heap to feed an algorithm that underestimates how many elements remain.

Related errors


AI-assisted analysis of krahets/hello-algo@69932aed18 (2026-08-13). Data as JSON: /api/errors/a5a210f14945a57f. Report an issue: GitHub.