我正在尝试理解使用堆排序对数组进行排序的代码(参考-https://www.sanfoundry.com/java-program-implement-heap-sort/)
"maxheap"函数使用此计算来获得左&节点的右子节点(在多个不同的示例/站点中使用相同的)
int left=2*i
int right=2*i+1;
上面的逻辑/推理是什么?
此外,在heatify函数中,调用maxheap-fn时,i=N/2->0
(例如,而不是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);
}
上面的逻辑/推理是什么?
Heap是一个二叉树,在一个基于1的索引数组中,如下图所示,要获得节点i
的左侧子节点,需要索引2*i
,右侧子节点需要索引2*i + 1
。
Array:
[1, 2, 3, 4, 5, 6, 7]
Binary tree:
1
/
2 3
/ /
4 5 6 7
此外,在heatify函数中,调用maxheap-fn时i=N/2->0(而不是i=0到N-1,例如)你对为什么要这样做有什么想法吗?
maxheap
或max_heapify
函数是一个获取数组和索引i
作为输入以维护最大堆属性的过程。max_heapify
的假设是节点i
的左子树和右子树是最大堆,但节点i
可能违反最大堆属性(它可能小于其子级)
这意味着,如果我们在所有数组元素上调用max_heapify
,所有节点都将保持最大堆属性,我们应该得到一个最大堆。然而,如果我们从数组的开头(树根)开始,我们不能假设左子树和右子树已经是最大堆,因此我们需要从末尾(树叶)开始,然后转到开头。此外,叶子没有孩子,所以它们已经是最大堆了,我们不需要对它们调用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]