我一直在使用“算法入门”教科书中的一些算法,特别是我正在尝试使二进制堆正常工作100%。我有一种奇怪的感觉,我正在使用的例子是不正确的,我想知道是否有人可以帮我指出正确的方向。
给定数组
int[ ] arr = { 1, 2, 3, 4, 7, 8, 9, 10, 14, 16 };
我从MaxHeapify获得的结果是
[ 16, 14, 9, 10, 7, 8, 3, 1, 4, 2 ]
但是,在进行了一些谷歌搜索后,我发现使用这个精确数组的人作为一个例子的结果是:
[ 16, 14, 10, 8, 7, 9, 3, 2, 4, 1 ]
令我困惑的是,我的MaxHeapify方法给出的结果满足Heap属性,但它与预期的不同。以下是我在Java中的实现
public static void BuildMaxHeap( int[ ] arr )
{
for( int i = (int)Math.floor( arr.length - 1 ); i >= 0; i-- )
MaxHeapify( arr, i );
}
public static void MaxHeapify( int[ ] arr, int i )
{
int left = 2 * i + 1;
int right = 2 * i + 2;
int largest = i;
if( left < arr.length && arr[ left ] > arr[ largest ] )
largest = left;
if( right < arr.length && arr[ right ] > arr[ largest ] )
largest = right;
if( largest != i )
{
int temp = arr[ i ];
arr[ i ] = arr[ largest ];
arr[ largest ] = temp;
MaxHeapify( arr, largest );
}
}
答案 0 :(得分:10)
你展示的堆都是有效的。没什么值得担心的。
订购子节点的方法有多种。
考虑最右边交换的最简单的情况:
14 14
10 9 vs 9 10
... ... ... ...
答案 1 :(得分:1)
你的堆是有效的。它们是不同的,因为当您不应用这些方法时,数组不一定要排序。这就是Heapsort的用途。只需要一个细节,在BuildMaxHeap中你可能想要改变
for( int i = (int)Math.floor( arr.length - 1 ); i >= 0; i-- )
到
for( int i = arr.length / 2; i >= 0; i-- )
我说这个的原因是因为你可以从最后一个有叶子的节点开始,因为叶子总是一个max_heap。