我正在尝试理解使用堆排序对数组进行排序的代码 (参考-https://www.sanfoundry.com/java-program-implement-heap-sort/)
“ maxheap”函数使用此计算来获取节点的左右子节点(在多个不同的示例/站点中使用相同的子节点)
int左= 2 * i;
int right = 2 * i +1;
以上内容的逻辑/原因是什么?
此外,在heapify函数中,使用i = N / 2-> 0调用maxheap fn
(例如,代替i = 0到N -1)
关于为什么要这样做的任何想法?
public static void heapify(int arr[])
{
N = arr.length-1;
for (int i = N/2; i >= 0; i--)
maxheap(arr, i);
}
答案 0 :(得分:0)
以上内容的逻辑/原因是什么?
堆是一棵二叉树,在基于1的索引数组中,如下所示,要获取节点i
的左子节点,您需要索引2*i
,对于右子节点,您将得到索引2*i + 1
。
Array:
[1, 2, 3, 4, 5, 6, 7]
Binary tree:
1
/ \
2 3
/ \ / \
4 5 6 7
另外,在heapify函数中,使用i = N / 2-> 0调用maxheap fn (例如,而不是i = 0到N -1)为什么要这么做呢?
maxheap
或max_heapify
函数是获取数组和索引i
作为维护最大堆属性的输入的过程。 max_heapify
的假设是节点i
的左右子树是最大堆,但是节点i
可能会违反max堆属性(可能小于其子级)。 br />
这意味着,如果我们在所有数组元素上调用max_heapify
,则所有节点都将保持maxheap属性,并且应该获得maxheap。但是,如果我们从数组的开头(树的根)开始,则不能假设左右子树已经是最大堆,因此,我们需要从结尾(树的叶子)开始并开始。
另外,叶子没有子代,因此它们已经是最大堆了,我们不需要在它们上调用max_heapify
。在具有n个元素的堆中,子数组[floor(n/2)+1..n]
中的节点是叶子,因此我们可以从floor(n/2)
循环到1
并仅在内部节点上调用max_heapify
。>
对于基于0的数组:
left(i): 2 * i + 1
right(i): 2 * i + 2
leaves: [floor(n/2)..n-1]
internal nodes: [0..floor(n/2)-1]