我所知道的所有排序算法都需要独占访问他们所使用的数据结构。是否有任何可以处理可随时更改的数据?
为了使这成为可能,我们当然可以假设:
我对任何信息,论文或实施感兴趣,如果他们有比上述更严格或更少的假设。
答案 0 :(得分:0)
许多数据结构按排序顺序维护数据。例如,任何树,跳过列表,堆等都允许有序访问。通常,插入,删除或更新数据项是O(log N)或更好(N =数据集中的项目数)。因此,您可以预期在一段时间间隔内维护数据集的排序不变量的成本为O(M * log(N)),其中M是您在该时间间隔内插入/删除/更新的项目数。
某些排序算法(例如插入排序)在数据部分排序时表现更好。充其量,运行这种算法的成本是O(N),但这只发生在非常有限的情况下。平均而言,您可以预期它更接近O(N * log(N))。
因此,如果需要始终维护数据集的排序不变量,则应使用索引或堆等数据结构。但是,如果您有时只需要获取数据,则只需缓冲数组中的更新并在需要时重新排序整个数据集可能更有效。
答案 1 :(得分:0)
大多数比较/交换排序应该能够主要对正在修改的数组进行排序。插入排序和Shell排序当然可以,冒险排序甚至选择排序。我对Quicksort并不完全确定。看起来如果数据值在排序中间发生了变化,某些实现可能会进入无限循环。
考虑插入排序的简单情况。从数组[4, 7, 5, 3, 2]
开始。
经过几次迭代后,你得到:[3, 4, 5, 7, 2]
。此时有人进入并将4
更改为1
,并为您提供[3, 1, 5, 7, 2]
。您的排序正在尝试放置最后一项2
。它最终会给你[3, 1, 2, 7, 5]
,因为它放置的最后一个元素就是你的最终数组。
在一个不经常更改的数组中,您可能只有一些项目不合适而且Insertion排序可以快速整理。
但是,您必须小心实施。因为其他线程可能正在修改数组,所以您不能拥有包含数组项内容的临时变量。如果数组中的项是不会改变的引用(即只有被引用的东西可以改变,而不是数组本身中的元素),那么暂时保存该引用是没有问题的。但是,如果数组是一个整数数组,则必须对实际的数组元素进行所有比较,而不是通过暂时保存一个值。
那就是说,这样的事情很不寻常。许多有序数据结构可以被编码为无锁,使得多个线程可以同时读取和/或写入。这消除了“近似”对任何事物进行排序的需要,因为数据结构始终保持秩序。