Python 中 Heapify 函数的意外结果
Unexpected Result from Heapify Function in Python
我运行下面这段代码
from heapq import heappop,heappush,heapify
nums = [12,3,-2,6,4,8,9]
heapify(nums)
print(nums)
并得到如下结果:
[-2, 3, 8, 6, 4, 12, 9]
但我希望得到以下结果:
[-2,4,3,12,6,8,9] 因为我希望我们在维护堆数据结构的同时将每个项目从 nums(从 12 开始,一个一个地)推入一个空列表。谁能给我一些指导,为什么我错了?
让我们画出您的初始数组:[12,3,-2,6,4,8,9]
12
/ \
3 -2
/ \ / \
6 4 8 9
heapify
函数不会重复插入建堆。它使用 Floyd 算法在 O(n) 时间内将数组重新排列为堆顺序。在 https://github.com/python/cpython/blob/master/Lib/heapq.py 中搜索 "heapify"。相关代码为:
for i in reversed(range(n//2)):
_siftup(x, i)
(出于某种未知原因,heapq 的作者决定将节点向叶级移动的操作称为“_siftup”,这非常令人困惑。大多数人将此操作称为“_siftdown”。如果您检查代码,虽然,节点肯定正在向叶级别移动。)
无论如何,堆中有7个节点。这将影响的第一个节点位于数组中的索引 3 处:值为 6 的节点。该节点无需执行任何操作,因为该节点已经处于叶级别。然后它尝试移动索引 2(值 -2)处的节点,但它根本没有筛选。值为 3 的节点也不会筛选。所以我们剩下根节点 12.
12 比两个 children 都大,所以它与最小的交换,给出:
-2
/ \
3 12
/ \ / \
6 4 8 9
而且它比这两个 children 都大,所以它再次与最小的交换:
-2
/ \
3 8
/ \ / \
6 4 12 9
那么数组表示就是[-2, 3, 8, 6, 4, 12, 9]
.
我觉得叫_siftup是因为(在CS课上),父节点也叫根节点,所以函数写起来的时候,树倒过来了
我运行下面这段代码
from heapq import heappop,heappush,heapify
nums = [12,3,-2,6,4,8,9]
heapify(nums)
print(nums)
并得到如下结果: [-2, 3, 8, 6, 4, 12, 9] 但我希望得到以下结果: [-2,4,3,12,6,8,9] 因为我希望我们在维护堆数据结构的同时将每个项目从 nums(从 12 开始,一个一个地)推入一个空列表。谁能给我一些指导,为什么我错了?
让我们画出您的初始数组:[12,3,-2,6,4,8,9]
12
/ \
3 -2
/ \ / \
6 4 8 9
heapify
函数不会重复插入建堆。它使用 Floyd 算法在 O(n) 时间内将数组重新排列为堆顺序。在 https://github.com/python/cpython/blob/master/Lib/heapq.py 中搜索 "heapify"。相关代码为:
for i in reversed(range(n//2)):
_siftup(x, i)
(出于某种未知原因,heapq 的作者决定将节点向叶级移动的操作称为“_siftup”,这非常令人困惑。大多数人将此操作称为“_siftdown”。如果您检查代码,虽然,节点肯定正在向叶级别移动。)
无论如何,堆中有7个节点。这将影响的第一个节点位于数组中的索引 3 处:值为 6 的节点。该节点无需执行任何操作,因为该节点已经处于叶级别。然后它尝试移动索引 2(值 -2)处的节点,但它根本没有筛选。值为 3 的节点也不会筛选。所以我们剩下根节点 12.
12 比两个 children 都大,所以它与最小的交换,给出:
-2
/ \
3 12
/ \ / \
6 4 8 9
而且它比这两个 children 都大,所以它再次与最小的交换:
-2
/ \
3 8
/ \ / \
6 4 12 9
那么数组表示就是[-2, 3, 8, 6, 4, 12, 9]
.
我觉得叫_siftup是因为(在CS课上),父节点也叫根节点,所以函数写起来的时候,树倒过来了