假设我有一个数组A =< 1,6,2,7,3,8,4,9,5> Heapsort的伪代码:
BUILD-MAX-HEAP(A)
n = A.heapsize = A.length
for i = floor(n/2) down to 1
MAX-HEAPIFY(A,i)
MAX-HEAPIFY(A,i)
n = A.heap-size
l = LEFT(i)
r = RIGHT(i)
if l <= n and A[l] > A[i]
largest = l
if r <= n and A[r] > A[largest]
largest = r
if largest != i
exchange A[i] <-> A[largest]
MAX-HEAPIFY(A,largest)
我知道BUILD-MAX-HEAP将首先调用MAX-HEAPIFY(A,4),它将交换7和9,然后在MAX-HEAPIFY(A,3)之后它将切换8和2.然后它将调用MAX-HEAPIFY(A,2),这是我感到困惑的地方。这是当MAX-HEAPIFY(A,2)被调用
时堆的外观首先要做的是交换6和7,然后调用MAX-HEAPIFY(A,4)(因为4现在最大),交换6和9,然后调用MAX- HEAPIFY(A,8)但是没有任何事情会发生,因为你已经到达了一个叶子,所以它会返回到调用它的函数。
MAX-HEAPIFY(A-8)被MAX-HEAPIFY(A,4)调用,所以返回它
MAX-HEAPIFY(A,4)被MAX-HEAPIFY(A,2)调用,所以返回它
但现在A [2]&lt; A [4](因为7&lt; 9),正是在这一点上,我想知道如何再次调用MAX-HEAPIFY(A,2)来交换7和9.当一个递归函数(或子程序)返回时对于调用它的那个,没有更多的代码可以执行(因为MAX-HEAPIFY只在函数的末尾调用MAX-HEAPIFY),所以它会返回递归堆栈,在我看来它感觉就像7仍然是9的父母
很抱歉,如果这令人困惑,但有人可以告诉我这一点,以帮助我了解这是如何递归地最大化堆积自己?
答案 0 :(得分:1)
以下是我在遵循算法时得到的一系列步骤(请注意我们在每个算法结束时递归时的缩进级别)。每次我们退出函数时,我们只返回主程序(调用max_heapify
,数字4为1)。我不肯定你的解释是什么,但我希望以下内容更清楚。
for i in (4,3,2,1):
MAX-HEAPIFY(A,i)
MAX-HEAPIFY(A,4):
largest=4 # initialized
l=8
r=9
largest=8 # calculated
swap A[4] and a[8]:
A = <1,6,2,9,3,8,4,7,5>
MAX-HEAPIFY(A, 8):
largest=8 # initialized
l=16
r=17
...return
...return
MAX-HEAPIFY(A,3):
largest=3 # initialized
l=6
r=7
largest=6 # calculated
swap A[3] and A[6]:
A = <1,6,8,9,3,2,4,7,5>
MAX-HEAPIFY(A, 6):
largest=6
l=12
r=13
...return
...return
MAX-HEAPIFY(A,2):
largest=2 # initialized
l=4
r=5
largest=4 # calculated
swap A[2]and A[4]:
A = <1,9,8,6,3,2,4,7,5>
MAX-HEAPIFY(A, 4):
largest=4 # initialized
l=8
r=9
largest=8
swap A[4] and A[8]:
A = <1,9,8,7,3,2,4,6,5>
MAX-HEAPIFY(A, 8):
largest=8 # initialized
l=16
r=17
...return
...return
...return
MAX-HEAPIFY(A,1):
largest=1 # initialized
l=2
r=3
largest=2 # calculated
swap A[1] and A[2]:
A = <9,1,8,7,3,2,4,6,5>
MAX-HEAPIFY(A, 2):
largest=2: # initialized
l=4
r=5
largest=4: # calculated
swap A[2] and A[4]:
A = <9,7,8,1,3,2,4,6,5>
MAX-HEAPIFY(A, 4):
largest=4: # initialized
l=8
r=9
largest=8: # calculated
swap A[4] and A[8]:
A = <9,7,8,6,3,2,4,1,5>
MAX-HEAPIFY(A, 8):
largest=8: # initialized
l=16
r=17
...return
...return
...return
...return
Done!
A = <9,7,8,6,3,2,4,1,5>
然后我甚至将你的算法(几乎直接)翻译成python(注意我必须对python的基于0的索引进行一些调整):
def build_max_heap(A):
for i in range(len(A)//2, 0, -1):
max_heapify(A, i)
def left(x):
return 2 * x
def right(x):
return 2 * x + 1
def max_heapify(A, i):
n = len(A)
largest = i
l = left(i)
r = right(i)
if l<=n and A[l-1] > A[i-1]:
largest = l
if r <=n and A[r-1] > A[largest-1]:
largest = r
if largest !=i:
A[i-1], A[largest-1] = A[largest-1], A[i-1]
max_heapify(A,largest)
if __name__ == '__main__':
A = [1,6,2,7,3,8,4,9,5]
build_max_heap(A) # modifies in-place
print(A)
这打印: [9,7,8,6,3,2,4,1,5] (这与我们的手动迭代一致)
...还有一次检查,使用python的heapq
模块及其私有方法_heapify_max
:
import heapq
A = [1,6,2,7,3,8,4,9,5]
heapq._heapify_max(A)
print(A)
...打印相同: [9,7,8,6,3,2,4,1,5]