krahets/hello-algo · error · IndexError
堆为空
Error message
堆为空
What it means
IndexError with message '堆为空' (heap is empty), raised by MaxHeap.pop. The implementation swaps the root with the last leaf, removes the leaf, then sifts down; calling pop on an empty heap would dereference an invalid root, so it is guarded with is_empty().
Source
Thrown at codes/python/chapter_heap/my_heap.py:77
def sift_up(self, i: int):
"""从节点 i 开始,从底至顶堆化"""
while True:
# 获取节点 i 的父节点
p = self.parent(i)
# 当“越过根节点”或“节点无须修复”时,结束堆化
if p < 0 or self.max_heap[i] <= self.max_heap[p]:
break
# 交换两节点
self.swap(i, p)
# 循环向上堆化
i = p
def pop(self) -> int:
"""元素出堆"""
# 判空处理
if self.is_empty():
raise IndexError("堆为空")
# 交换根节点与最右叶节点(交换首元素与尾元素)
self.swap(0, self.size() - 1)
# 删除节点
val = self.max_heap.pop()
# 从顶至底堆化
self.sift_down(0)
# 返回堆顶元素
return val
def sift_down(self, i: int):
"""从节点 i 开始,从顶至底堆化"""
while True:
# 判断节点 i, l, r 中值最大的节点,记为 ma
l, r, ma = self.left(i), self.right(i), i
if l < self.size() and self.max_heap[l] > self.max_heap[ma]:
ma = l
if r < self.size() and self.max_heap[r] > self.max_heap[ma]:
ma = rView on GitHub (pinned to 69932aed18)
Solutions
- Check heap.is_empty() before each pop.
- Drive the drain loop with while not heap.is_empty(): val = heap.pop().
- If you must pop a fixed count, clamp the count to heap.size().
Example fix
// before
while True:
top = heap.pop() # raises on last iteration
// after
while not heap.is_empty():
top = heap.pop() Defensive patterns
Strategy: validation
Validate before calling
def safe_pop(heap):
if heap.is_empty():
return None
return heap.pop() Type guard
def heap_has_items(heap) -> bool:
return not heap.is_empty() Try / catch
try:
val = heap.pop()
except IndexError:
val = None Prevention
- Always drive heap-drain loops with while not heap.is_empty().
- Track an external count and clamp pop operations to it.
- Reset or recreate the heap between independent runs.
When it happens
Trigger: Calling heap.pop() when size() == 0 — e.g. draining the heap in a loop without an is_empty guard, or popping more elements than were pushed.
Common situations: A while True loop that pops until exhausted but forgets the termination check; off-by-one in a k-largest/k-smallest selection that pops one too many times; reusing a heap instance across runs without resetting size tracking.
Related errors
AI-assisted analysis of krahets/hello-algo@69932aed18 (2026-08-13).
Data as JSON: /api/errors/55a8daa704bdb531.
Report an issue: GitHub.