在优先级队列的这个实现上,我必须使用递归来确定我作为方法IsMaxHeap
的参数接收的数组是否是最大堆。
我想确保我评估所有可以使这项工作或不能正常工作的案例。
static boolean isMaxHeap(int[] H, int idx) {
if(2*idx == (H.length -1) && H[2 * idx] <= H[idx])
return true;
if(2*idx > (H.length -1))
return true;
if ((2*idx+1) == (H.length -1) && H[2 * idx] <= H[idx] && H[2 * idx + 1] <= H[idx])
return true;
if((2*idx+1) > (H.length -1))
return true;
if (H[2 * idx] <= H[idx] && H[2 * idx + 1] <= H[idx])
return isMaxHeap(H, (idx + 1));
else
return false;
}
你能帮帮我吗?
答案 0 :(得分:1)
您的代码很难理解,因为您在条件中进行了很多计算。因此很难说它是否真的有效。此外,您所编写的内容基本上是for
循环的递归实现。也就是说,检查节点1,2,3,4,5等。
虽然这可行,但最终会使用O(n)堆栈空间。如果你有一个非常大的堆(比如几十万个项目),你就冒着堆栈溢出的风险。
递归实现此方法的一种更常见的方法是对树进行深度优先遍历。也就是说,你跟随左边的孩子一直到根,然后上升一级并检查该节点的正确子节点,并将其左边的子节点一直到根,等等。所以,给定这个堆:
1
2 3
4 5 6 7
8 9 10 11 12 13 14 15
您将按以下顺序检查节点:[1,2,4,8,9,5,10,11,3,6,12,13,7,14,15]
这样做可以简化代码并将堆栈深度限制为O(log n),这意味着即使有一百万个节点,您的堆栈深度也不会超过20。
由于您正在使用2*idx
和2*idx+1
来查找子项,因此我假设您的阵列已设置为根节点位于索引1处。如果root位于索引0处,然后这些计算将是:2*idx+1
和2*idx+2
。
static boolean isMaxHeap(int[] H, int idx)
{
// Check for going off the end of the array
if (idx >= H.length)
{
return true;
}
// Check the left child.
int leftChild = 2*idx;
if (leftChild < H.length)
{
if (H[leftChild] > H[idx])
return false;
if (!isMaxHeap(H, leftChild)
return false;
}
// Check the right child.
int rightChild = 2*idx + 1;
if (rightChild < H.length)
{
if (H[rightChild] > H[idx])
return false;
return isMaxHeap(H, rightChild);
}
return true;
}