算法复习。为什么heapsort是insort算法?


15

我看不到为什么heapsort被认为是就地排序算法。

我的意思是用要排序的数组元素(即堆)填充的额外数据结构用于协助提取最小值和排序过程。

那么我可能误解了inplace的定义吗?

但是,例如,插入排序显然是就地算法,即元素不需要额外的内存。

那么为什么要考虑到它呢?

Answers:


12

我的意思是用要排序的数组元素(即堆)填充的额外数据结构用于协助最小值的提取和排序过程。

不。将数组转换为符合堆约束,而无需使用超过O(1)的额外内存。(实际上,您需要的额外内存足以容纳数组的一个元素(用于交换),再加上一个或两个布尔值以及一个或两个循环变量)。

好的,从技术上讲,通常可以将堆排序解释为使用单独的堆,但是完全可以就地实现它。


3
我唯一希望看到带有单独堆(在代码中)的“ heapsort”的地方是像Haskell这样的功能语言,出于同样的原因,通常的功能“ Quicksort”也没有就位-函数式程序员他们的列表很多,并且就地排序是有状态的-它会更改数组/包含数据的内容的状态。吓一跳,因为我真的不接受异位快速排序根本就是快速排序,或者异位堆完全根本就是堆排序-至少在没有明确说明它不在位的情况下,地点。
Steve314,2011年

1
@ Steve314,我想我已经看过一些教材,其中讲了一些内容,即“将其放入堆中,然后一次将元素拉出并放入数组中”。但是,刚刚检查了CLR之后,我可以报告它们确实显示了就地版本。
彼得·泰勒

2
@PeterTaylor:是的,我正在阅读的书(Skiena)通过建立一个额外的堆来介绍堆排序。
user10326 2011年

4

您可能缺少基本的理解,即可以使用数组来指定树的布局。

假设您有一棵二叉树,并且内部节点位于数组的索引i处。然后可以通过以下方式找到该节点的父级和子级的数组索引:

Parent(i) = floor(i/2)
Left child(i) = 2i
Right child(i) = 2i + 1

看到:

http://www.personal.kent.edu/~rmuhamma/Algorithms/MyAlgorithms/Sorting/heapSort.htm

由于可以将堆完全保留和组织在一个数组中,因此可以通过在输入数组内部移动元素来使heapsort在原地运行。实际上,堆是使用原始输入数组构建和操纵的。


:我知道这一点。问题似乎是我正在阅读的书使用单独的堆展示了heapsort。像这样呈现)
user10326 2011年

我强烈建议您购买Cormen等人的“算法简介”这本书。它清楚地回答了所有与算法有关的问题。如果您认真对待计算机科学家或软件工程师的职业,那么您需要拥有这本书。
stackoverflowuser2010

1

如您所说,如果确实需要一个额外的结构来构建堆,那么heapsort确实不是就地排序算法。

然而,这种情况并非如此。您可以在要排序的同一数组上构建堆,然后应用heapsort算法,以便就地排序。


基本上,有一个“堆”算法,用于对数组中的数据进行重新排序,使其符合IIRC O(n)时间中的堆规则。查看该伪programmers.stackexchange.com/questions/116904/...。在那之后,主要是重复进行堆根提取,并跟踪仍然有多少堆是“堆”以及对最终结果进行排序的问题。
Steve314,2011年

0

在计算机科学中,就地算法(或就地拉丁语而言)是一种使用数据结构转换输入的算法,该数据结构具有少量恒定的额外存储空间。算法执行时,输入通常会被输出覆盖。非原位算法有时称为非原位或非原位。

维基百科-就地算法


那么,为什么将mergesort视为非原位算法?
2011年

3
这不是有用的答复。它与堆排序无关,也不能回答问题。
stackoverflowuser2010

当然,它与heapsort有关。从定义中应该清楚,Heapsort是就地排序算法。实际上,它是从堆排序页面链接的。
Rein Henrichs

0

之所以认为它是适当的,是因为它的空间要求可以忽略不计(如果您使用按位运算来交换项目,则它的常数是恒定的,或者根本不存在)。例如,没有MergeSort,因为在搜索示例的每次迭代中都没有修改输入集。

说明就地算法与就地算法之间差异的最好方法可能是看一下下面的C / C ++字符串反转代码(从K&R开始):

void reverse(char s[])
{
      int c, i, j;

      for (i = 0, j = strlen(s)-1; i < j; i++, j--) {
         c = s[i];
         s[i] = s[j];
         s[j] = c;
      }
}

例如,如果您从末尾读取输入字符串并将字符放置在另一个缓冲区中,那将是一种异位字符串反转算法。


1
Mergesort真是令人讨厌-容易错误地使自己相信自己拥有就地策略。通常,它仅适用于小型阵列。但是,我认为我曾经下载过一篇论文,有人其中完成了归类排序算法的就地变体。我看看是否可以再次找到它。
Steve314,2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.