Heapsort:构建最大堆过程说明

时间:2018-12-24 22:31:33

标签: algorithm heap heapsort minmax-heap

我正在尝试理解使用堆排序对数组进行排序的代码 (参考-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);        
}

1 个答案:

答案 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)为什么要这么做呢?

maxheapmax_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]