"sort in place"的意思是就地排序。
回到排序问题,如果考虑到一堆打孔卡片,通过重新排列“原地”避免复制打孔卡片进行排序会更好。
一些排序算法支持这种原地操作方式,而其他算法则不支持。
然而,所有算法都需要一些额外的存储空间来存储工作变量。如果目标仅是通过连续修改输入来生成输出,那么可以通过保留大块内存来定义这样的算法,使用它来产生一些辅助数据结构,然后使用它来指导这些修改。你仍然是通过在原地转换输入来生成输出,但你正在破坏整个练习的意义——你没有节省空间。
因此,原地定义的正常定义要求您达到一定的空间效率标准。使用与输入成比例的额外空间(即O(n)额外空间)并仍将您的算法称为“原地”是绝对不可接受的。
维基百科页面上关于原地算法的描述称,一个原地算法只能使用常数级别(O(1))的额外空间。
在计算机科学中,原地算法(或拉丁语中的in situ)是一种使用具有小型、恒定数量的额外存储空间的数据结构来转换输入的算法。
在计算复杂性部分中有一些技术细节,但结论仍然是例如快速排序需要O(log n)的空间(正确),因此不是原地的(我认为是错误的)。
O(log n)比O(n)要小得多 - 例如16,777,216的以2为底的对数是24。
快速排序和堆排序通常被认为是就地排序,而堆排序可以用O(1)的额外空间实现(我之前对此有误)。归并排序更难以就地实现,但是其非就地版本非常适合缓存 - 我怀疑实际实现接受O(n)的空间开销 - 内存便宜但内存带宽是主要瓶颈,因此将内存换成缓存效率和速度通常是一个不错的选择。【注:在上述内容中,我假设了数组的就地归并排序。链表的就地归并排序非常简单。关键区别在于合并算法 - 对两个没有复制或重新分配的链接列表进行合并很容易,但是在不使用O(n)辅助存储器的情况下对更大数组的两个子数组执行相同操作的AFAIK不行】快速排序算法即使是就地排序,也具有高缓存效率,但由于其最坏情况的行为,可能会被取消作为就地算法。在退化情况下(通常是输入已经排序的非随机版本),运行时间为O(n^2),而不是预期的O(n log n)。在这种情况下,额外的空间需求也增加到了O(n)。然而,对于大型数据集并采取一些基本预防措施(主要是随机选择枢轴),这种最坏情况的行为变得极不可能发生。
我个人认为,在就地算法中,O(log n)的额外空间是可以接受的 - 这不是作弊,因为它没有违反就地工作的原始目的。
然而,我的观点当然只是我的观点。
还有一个额外的注意事项 - 有时候,人们会将一个函数称为就地函数,仅仅是因为它有一个参数既用于输入也用于输出。这并不一定意味着该函数是空间高效的,结果是通过转换输入产生的,甚至该参数仍然引用同一内存区域。这种用法不正确(规范主义者会这样说),尽管它很常见,最好是意识到它但不要过于担心。
可以通过使用交换函数来完成,而不是创建一个全新的结构体,我们甚至不知道该算法的名称就能实现它 :D
我不确定这些概念是否足够相似,可以像建议的那样进行比较。是的,它们都涉及排序,但一个是关于人类可理解(自然)的排序顺序,而另一个则定义了一种算法,通过覆盖现有结构来实现高效排序,而不是使用额外的数据结构(如冒泡排序)。