【发布时间】:2017-04-25 04:20:27
【问题描述】:
我在考试中得到了这个问题,但我不确定我是否理解它要我做什么。如果我做了正确的事情,你能澄清一下吗?
问题
一个整数数组 A 被传递给函数makeHeap。如果 A[0] 包含 n,则 A[1] 到 A[n-1] 包含任意顺序的数字。写 makeHeap 使得 A[1] 到 A[n-1] 包含一个最小堆。您的函数必须通过按 A[2]、A[3]、...、A[n-1] 的顺序处理元素来创建堆。
我的解决方案
void makeHeap(int A[], int n)
{
int r = n -1 ;
for(int i = 1; i <= n/2; i++)
siftUp(a, i , r );
}
/* i- parent , r - right of the array */
void siftUp(int A[], int i , int r )
{
boolean done = false ;
int j = 2* i ;
while (j <= r && !done)
{
if(A[j] > A[j+1]) // find the smalest child
j+=1 ;
if(A[i] > A[j])
{
// code to swap A[i] and A[j]
i = j ;
j = i*2 ;
}
else done = true ;
}
}
这个解决方案甚至远程正确吗?另外,siftUp 是函数的正确名称吗?
编辑:
我的新解决方案
void makeHeap(int A[], int n)
{
for(int i = 1; i <= A[0]/2; i++)
siftUp(A, i );
}
/* i- parent */
void siftUp(int A[], int i )
{
bool done = false ;
int j = 2* i ;
while (i > 1 && !done)
{
if(A[j] > A[j+1]) // find the smallest child
j+=1 ;
if(A[i] > A[j])
{
/* swap A[j] and A[i] */
int temp = A[i];
A[i] = A[j];
A[j] = temp ;
j = i ;
i = i / 2 ;
}
else done = true ;
}
}
【问题讨论】:
-
您的“交换”代码不正确 - 所以不,它不是远程正确的。我不清楚你需要
r参数到siftUp();知道您正在筛选哪个节点就足够了。您从该叶节点(在您向上筛选时从堆中最右边的节点开始)向根移动。你很幸运;A[0]持有堆大小的方案为您提供了一个基于 1 的堆结构,它比基于 0 的结构更易于编码。 -
你正在做的是一系列插入到堆中。您必须插入所有项目。所以你的
makeHeap循环终止条件必须是i < n,而不是i <= n/2。 -
但是如果 i 一直到 n,那么 sift up 函数将不会执行一半的时间。即因为 j = i * 2
-
@JonathanLeffler 这是在考试中出现的,所以我认为这将是对我们在课堂上学习的算法的简单修改。因此我忽略了我们不需要 r 的事实。我认为这个 nieve 假设导致我无法正确解决问题。请看我的编辑,我现在对我的解决方案的正确性更有信心。
标签: c++ c algorithm heap min-heap