【问题标题】:Sorting in place就地排序
【发布时间】:2013-05-11 05:34:54
【问题描述】:

“就地排序”是什么意思?

【问题讨论】:

  • 它们没有可比性:就地排序是排序算法的一个特征,自然排序是指你想要收藏的顺序排序。因此,您可以使用自然排序进行就地排序。
  • 一般语义中in-place的含义here.

标签: algorithm sorting


【解决方案1】:

就地算法的想法并不是排序所独有的,但排序可能是最重要的情况,或者至少是最广为人知的情况。这个想法是关于空间效率的——使用最少数量的 RAM、硬盘或其他您可以摆脱的存储空间。这在几十年前尤其重要,当时硬件更加有限。

这个想法是通过连续转换数据直到产生输出,在包含输入的相同内存空间中产生输出。这避免了使用两倍存储空间的需要——一个区域用于输入,一个相同大小的区域用于输出。

排序是一个相当明显的例子,因为排序可以通过重复交换项目来完成 - 排序只会重新排列项目。交换不是唯一的方法 - 例如,Insertion Sort 使用稍微不同的方法,相当于进行一系列交换,但速度更快。

另一个例子是matrix transposition - 同样,这可以通过交换物品来实现。添加两个非常大的数字也可以通过从最低有效数字开始并向上传播来就地完成(结果替换其中一个输入)。

回到排序,当您想到成堆的punched cards 时,“就地”重新排列的优势变得更加明显 - 最好避免为了排序而复制打孔卡片。

一些排序算法允许这种就地操作,而另一些则不允许。

但是,所有算法都需要一些额外的存储空间来存储工作变量。如果目标只是通过连续修改输入来产生输出,那么通过保留大量内存来定义算法是相当容易的,使用它来产生一些辅助数据结构,然后使用它来指导这些修改。您仍然通过“就地”转换输入来产生输出,但是您正在挫败练习的全部要点 - 您没有节省空间。

因此,就地定义的正常定义要求您达到某种空间效率标准。使用与输入成比例的额外空间(即 O(n) 额外空间)并仍然将您的算法称为“就地”是绝对不可接受的。

关于就地算法的Wikipedia page 目前声称就地算法只能使用恒定数量 - O(1) - 的额外空间。

在计算机科学中,就地算法(或拉丁语中的原位算法)是一种使用具有少量恒定额外存储空间的数据结构来转换输入的算法。

In Computational Complexity 部分中指定了一些技术细节,但结论仍然是,例如快速排序需要 O(log n) 空间(真),因此不是原位的(我认为这是错误的)。

O(log n) 比 O(n) 小 很多 - 例如 16,777,216 的底数 2 对数是 24。

Quicksort 和 heapsort 通常都被认为是 in-place,并且 heapsort 可以用 O(1) 额外空间来实现(我之前弄错了)。 Mergesort 更难就地实现,但非就地版本对缓存非常友好——我怀疑现实世界的实现会接受 O(n) 空间开销——RAM 很便宜,但内存带宽是主要瓶颈,因此,用内存换取缓存效率和速度通常很划算。

[编辑 当我写以上内容时,我假设我正在考虑对数组进行就地合并排序。链表的就地合并排序非常简单。关键区别在于合并算法 - 合并两个链表而不复制或重新分配很容易,对更大数组的两个子数组(并且没有 O(n) 辅助存储)做同样的事情 AFAIK 不是.]

快速排序也是缓存效率高的,即使是就地的,但由于诉诸其最坏情况的行为,可能会被取消为就地算法的资格。有一个退化的情况(在非随机版本中,通常当输入已经排序时),运行时间是 O(n^2) 而不是预期的 O(n log n)。在这种情况下,额外的空间需求也增加到 O(n)。然而,对于大型数据集和一些基本的预防措施(主要是随机枢轴选择),这种最坏情况的行为变得非常不可能。

我个人的观点是,O(log n) 额外空间对于就地算法是可以接受的——这不是作弊,因为它不会破坏就地工作的初衷。

但是,我的意见当然只是我的意见。

还有一点需要注意 - 有时,人们会就地调用函数,因为它的输入和输出都只有一个参数。这并不一定意味着该函数是节省空间的,结果是通过转换输入产生的,或者甚至参数仍然引用相同的内存区域。这种用法是不正确的(或者prescriptivists 会声称),尽管它很常见,最好注意但不要为此感到压力。

【讨论】:

    【解决方案2】:

    就地排序意味着无需任何额外空间即可进行排序。根据wiki,它说

    就地算法是一种使用具有少量恒定额外存储空间的数据结构来转换输入的算法。

    Quicksort 是就地排序的一个示例。

    【讨论】:

    • @cmbaxter - O(log n) 空间比 O(n) 空间好很多,这是关键点。少量不一定是恒定的量。非就地算法会生成一个新副本,而旧副本仍然保留。需要 O(n) 空间的算法不符合就地算法的资格,因为使用 O(n) 空间只是为了弄清楚如何进行交换被认为是作弊(击败重点)。
    • 爱维基百科。 In Place Sort 文章指出,Quicksort 没有到位,因为它没有使用恒定大小的数据结构。但是,如果您阅读 Quicksort 文章,它说它可以通过就地排序来完成。难怪人们对这样的事情感到困惑:)
    • @Steve314,链表上的合并排序可以使用 O(1) 空间和 O(n log n) 时间,只要您考虑原始对象的链接部分。
    • @Steve314 堆排序可以迭代完成,不需要栈。
    • @Steve314,它与堆栈无关。合并通过将项目从一个列表移动到另一个列表来工作,您可以通过更改链接来完成此操作而无需额外空间。您唯一需要跟踪的是一个列表的结束位置和另一个列表的开始位置,您可以使用一个变量来告诉您列表的长度(因为除了最后一个之外的所有列表都具有相同的长度)。
    【解决方案3】:

    我不认为这些术语密切相关:

    就地排序是指通过直接在列表中修改元素顺序来对现有列表进行排序。与之相反的是保持原样,并按顺序创建一个新列表

    自然排序是一个描述完整对象如何以某种方式排序的术语。例如,您可以说 0 低于 1(整数的自然排序)或 A 按字母顺序排在 B 之前(字符串的自然排序)。你很难说 Bob 一般 比 Alice 大或小,因为它在很大程度上取决于特定属性(按字母顺序按姓名、年龄、收入...)。因此,人没有自然的顺序

    【讨论】:

    • 我同意您的评论,但维基百科说“就地算法是一种使用具有少量、恒定额外存储空间的数据结构来转换输入的算法。”
    【解决方案4】:

    我不确定这些概念是否足够相似,无法按照建议进行比较。是的,它们都涉及排序,但一个是关于人类可以理解(自然)的排序排序,另一个定义了一种算法,通过覆盖现有结构而不是使用额外的数据结构(如冒泡排序)

    【讨论】:

      【解决方案5】:

      它可以通过使用交换函数来完成,而不是创建一个全新的结构,我们实现该算法甚至不知道它的名称:D

      【讨论】:

        猜你喜欢
        • 2010-10-02
        • 2017-09-04
        • 2020-12-28
        • 1970-01-01
        • 1970-01-01
        • 2013-10-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多