【问题标题】:In what order does a minheap sort?最小堆排序的顺序是什么?
【发布时间】:2020-09-18 19:29:35
【问题描述】:

我一直在阅读有关 minHeap 和 maxHeap 的各种定义。我偶然发现了这样的陈述:

  1. minHeap 用于降序排序。
  2. maxHeap 用于升序排序。

取自 https://www.geeksforgeeks.org/heap-sort-for-decreasing-order-using-min-heap/ 中“注释”的语句。 但是当我在 Java 中使用 PriorityQueue<Integer> 和默认比较器实现 minHeap 并 poll() 它时,我得到了最小元素。这是为什么? 感谢任何试图提供帮助的人:)。

【问题讨论】:

  • 你从哪里引用?最小堆的想法是有效地访问最小值,重复这样做似乎不会导致升序。
  • @Yunnosch geeksforgeeks.org/heap-sort-for-decreasing-order-using-min-heap ...查看此处的“注释”
  • edit 在您的问题中直接提供该信息,而不是将其隐藏在 cmets 中。
  • @Yunnosch Done..你知道哪个是正确的吗?
  • 我阅读了链接,您似乎正确地引用/总结了。我期待看到一个解释。

标签: java algorithm sorting data-structures heap


【解决方案1】:

博客中的解释是正确的

在仔细研究heapSort() 函数时,它巧妙地利用了最小堆。数组的最小元素被最后一个元素替换,堆大小减少 1 再次heapify() it。

arr[0] -> 代表最小的元素。

在每次迭代中,对于从 n-10i,arr[0] 与 arr[i] 交换,并且堆再次堆化,大小比上一次迭代小 1。

【讨论】:

  • 为什么我们需要这样做?我们不能只轮询 0 索引并从 1 到 n 堆积吗?
  • 队列未被使用。数组已被使用。因此,作者能做的最好的事情就是将索引 0 处的元素与最后一个元素交换并堆化。这是一种通过交换来轮询自己
  • 谢谢..但是忘记文章了... minHeap 一般按什么顺序排序(不在文章中)?
【解决方案2】:

基本思想是就地排序。每次算法从堆中轮询时,堆大小都会缩小一。因此,数组末尾的一个位置不再是堆的一部分。在该索引中放置第 n 个最小的数字。

// One by one extract an element from heap 
for (int i = n - 1; i >= 0; i--) { 
    // Move current root to end 
    swap(arr[0], arr[i]); 

    // call max heapify on the reduced heap 
    heapify(arr, i, 0); 
}

因此,使用PriorityQueue 的算法表现如此奇怪的原因是您使用单独的数组进行输出。您可以切换到最大堆并坚持您的方法,也可以反向填充输出数组。两者都应该产生相同的行为。

【讨论】:

    【解决方案3】:

    min-heap 和 max-heap 不排序。您可以使用最小堆或最大堆进行排序,但在标准使用中,堆不排序。相反,它们以所谓的堆顺序排列。这种安排使添加项目和删除最小(或最大)的项目变得高效,同时保持数据的正确顺序。

    例如,这是一个最小堆的图示:

                    1
                3       2
              4   7   6   5
    

    这遵循没有孩子大于其父母的规则。该堆的结果数组表示为[1,3,2,4,7,6,5]。请注意,还有其他具有相同数字的有效堆。例如,以下两个都是有效的:

                    1                          1
                2       5                  2       3
              4   3   6   7              4   5   6   7
    

    对应的数组表示为[1,2,5,4,3,6,7][1,2,3,4,5,6,7]

    Max-heap 类似,除了规则是没有子节点不能大于其父节点。

    Wikipedia article on binary heap 很好地解释了这一切。

    现在,当您谈论使用堆排序时,您会构建一个堆,然后反复将根元素与数组中的最后一个元素交换,减少计数,然后重新堆化。所以你从后到前构建排序数组。如果使用最小堆,则根(最小值)将位于数组的末尾。

    因此,如果您想使用堆排序按降序排序,则使用最小堆。

    【讨论】:

    • 感谢您的详细解释:)
    猜你喜欢
    • 2011-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-27
    • 1970-01-01
    • 2011-02-19
    • 2019-02-28
    • 1970-01-01
    相关资源
    最近更新 更多