【问题标题】:Heapsort: Build max heap procedure explanationHeapsort: Build max heap 过程解释
【发布时间】:2019-05-23 21:26:14
【问题描述】:

我正在尝试理解使用堆排序对数组进行排序的代码 (参考 - https://www.sanfoundry.com/java-program-implement-heap-sort/

“maxheap”函数使用此计算来获取节点的左右子节点(在多个不同的示例/站点中使用相同)

int left = 2*i;
int 右 = 2*i + 1;

上述的逻辑/推理是什么?

另外,在 heapify 函数中,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);        
}

【问题讨论】:

    标签: algorithm heap heapsort minmax-heap


    【解决方案1】:

    上述的逻辑/推理是什么?

    堆是一个二叉树,在一个从 1 开始的索引数组中,如下所示,要获取节点 i 的左子节点,您需要索引 2*i,而右子节点则需要索引 @987654323 @。

    Array:
    [1, 2, 3, 4, 5, 6, 7]
    
    Binary tree:
    
             1
          /     \
       2           3
     /   \       /   \
    4     5     6     7
    

    另外,在 heapify 函数中,maxheap fn 以 i = N/2 -> 0 调用 (例如,而不是 i = 0 到 N -1。)关于为什么这样做的任何想法?

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

    【讨论】:

    • 感谢详细的解释!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-14
    • 2018-10-31
    • 2018-01-10
    相关资源
    最近更新 更多