{"record":{"id":"38f05d64e3814e32","repo":"krahets/hello-algo","slug":"error-38f05d","errorCode":null,"errorMessage":"堆積為空","messagePattern":"堆積為空","errorType":"exception","errorClass":"IndexError","httpStatus":null,"severity":"error","filePath":"zh-hant/codes/python/chapter_heap/my_heap.py","lineNumber":77,"sourceCode":"\n    def sift_up(self, i: int):\n        \"\"\"從節點 i 開始，從底至頂堆積化\"\"\"\n        while True:\n            # 獲取節點 i 的父節點\n            p = self.parent(i)\n            # 當“越過根節點”或“節點無須修復”時，結束堆積化\n            if p < 0 or self.max_heap[i] <= self.max_heap[p]:\n                break\n            # 交換兩節點\n            self.swap(i, p)\n            # 迴圈向上堆積化\n            i = p\n\n    def pop(self) -> int:\n        \"\"\"元素出堆積\"\"\"\n        # 判空處理\n        if self.is_empty():\n            raise IndexError(\"堆積為空\")\n        # 交換根節點與最右葉節點（交換首元素與尾元素）\n        self.swap(0, self.size() - 1)\n        # 刪除節點\n        val = self.max_heap.pop()\n        # 從頂至底堆積化\n        self.sift_down(0)\n        # 返回堆積頂元素\n        return val\n\n    def sift_down(self, i: int):\n        \"\"\"從節點 i 開始，從頂至底堆積化\"\"\"\n        while True:\n            # 判斷節點 i, l, r 中值最大的節點，記為 ma\n            l, r, ma = self.left(i), self.right(i), i\n            if l < self.size() and self.max_heap[l] > self.max_heap[ma]:\n                ma = l\n            if r < self.size() and self.max_heap[r] > self.max_heap[ma]:\n                ma = r","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/krahets/hello-algo/blob/69932aed1891a7b7f6a0de88cd116d3fe13e7032/zh-hant/codes/python/chapter_heap/my_heap.py#L59-L95","documentation":"Raised by the pop() method of a max-heap when attempting to extract the root element from a heap with zero nodes. The method first checks is_empty() (which compares size() to 0), then swaps the root with the last leaf, removes it, and sifts down. Unlike peek() which accesses max_heap[0] without a guard, pop() has explicit emptiness protection.","triggerScenarios":"Calling heap.pop() on a MaxHeap constructed from an empty list; draining all elements with repeated pop() and then calling pop() once more; constructing MaxHeap([]) and immediately extracting.","commonSituations":"Priority-queue consumers that process all items and then attempt one more pop; heap-sort implementations that pop exactly n+1 times; testing with empty input arrays.","solutions":["Check heap.is_empty() before calling pop()","Use heap.size() as the loop bound when draining all elements","Wrap in try/except IndexError for defensive extraction"],"exampleFix":"# before\nval = heap.pop()\n\n# after\nif not heap.is_empty():\n    val = heap.pop()\nelse:\n    val = None","handlingStrategy":"validation","validationCode":"if not heap.is_empty():\n    val = heap.pop()\nelse:\n    val = None","typeGuard":null,"tryCatchPattern":"try:\n    val = heap.pop()\nexcept IndexError:\n    val = None","preventionTips":["Check is_empty() before pop() in priority-queue consumer loops","Use heap.size() as the loop bound when draining all elements","Construct MaxHeap([]) carefully — it starts empty"],"tags":["data-structure","heap","python","priority-queue"],"backgroundTag":null,"analyzedSha":"69932aed1891a7b7f6a0de88cd116d3fe13e7032","analyzedAt":"2026-08-13T23:02:37.581Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}