CLRS练习:6.5-8
操作HEAP-DELETE(A,i)
从堆i
中删除节点A
中的项目。给HEAP-DELETE
的实现在O(lg n)
时间运行n元素最大堆。
我想知道输入A[10]={84,22,19,21,3,10,6,5,20}
(索引以1开头)并删除A[6]=10
的算法是否错误。用A[6]
替换最后一个节点将导致违反堆属性,忽略父值。
我为此编写了一个算法,想知道它是否正常或我在哪里出错?
HEAP-DELETE(A,i)
A[i]=A[A.heapsize]
A.heapsize-=1
while i>1 and A[parent(i)]<A[i]
swap A[i] with A[parent(i)]
i=parent(i);
答案 0 :(得分:2)
从最大堆中删除节点时,我们需要做的第一件事是将目标元素与最后一个元素交换,然后删除最后一个元素。
现在,我们遇到了修复最大堆的问题,因为我们只是移动了一个元素。让我们将我们刚刚移动的元素称为x
。
有三种情况:
x
大于其父x
小于其父x
等于其父如果x
等于其父级,那很容易 - 我们什么都不做。
如果x
小于其父级,我们需要做的就是MAX-HEAPIFY
(我假设您从评论中了解其工作原理),因为我们需要修复x
以下的任何错误。
如果x
大于其父级,我们会遇到您提出的问题。处理这个并不太棘手 - 我们只需要将x
与其父级进行比较,如果x
大于父级,我们就会交换它们。继续此过程,直到x
不再大于其父级或我们到达根目录(当x
没有父级时)。
话虽如此,你发布的伪代码对我来说是对的。干得好!)
答案 1 :(得分:0)
不确定这是否是一个错字,但看起来你实际上在这里增加:
A.heapsize - = - 1
如果A实际上是&#34;属性&#34;在阵列A中,我不认为你甚至可以改变它,但我可能是错的。当然,如果它只是你拥有的一些变量,那就没问题了。
除此之外,您的伪代码至少似乎处于正常工作状态。如果它还没有工作,可能会发布整个代码吗?
答案 2 :(得分:0)
这是伪代码:
HEAP-DELETE(A, i):
A[i] = A[A.heap-size]
A.heap-size -= 1
// Case : 8, 7 3, 5 6 1 2, 4 and delete 1
while(i > 1 and A[Parent(i)] < a[i])
swap A[i] with A[parent(i)]
i = Parent(i)
// Case : 10, 9 6, 8 7 5 4, 3 and delete 6
MAX-HEAPIFY(A, i)
答案 3 :(得分:0)
这是一个更简单的版本,你的最大堆是A,你想删除i位置的元素
DELETE(A, i)
HEAP-INCREASE-KEY(A, i, A[0]+1)
HEAP-EXTRACT-MAX(A)
以下是它的工作原理,HEAP-INCREASE-KEY增加你要删除的元素的值,以便大于root,这会将元素带到堆的根,然后调用HEAP- EXTRACT-MAX,根(要删除的元素)从堆中删除(并返回)