我正在寻找一种有效的算法来执行以下操作:给定N个项目的数组,以某种方式对其进行排序,使得项目变为M个相等的组,其中每个组都是未排序的,但是组之间是相互排序的(一组中的所有元素都小于下一组中的任何元素。)
最简单的方法是对整个数组进行排序。但它效率低下,特别是如果组的数量远小于项目总数(例如,将一百万个项目分成5组)。
目前我已决定使用quickselect算法(具体来说,它是Floyd-Rivest variation)将数组分类为2个未排序的组,然后将其应用M-1次。一个显着的改进可能是对快速选择应用分而治之的方法,首先将数组分成两组,然后对每一半进行排序等,直到我们有M组。类似于unordered partial sorting问题的概括。
但我有一种直觉,认为可能有一种更简单,更有效的方法解决问题。有什么我想念的吗?有任何想法吗?我需要这个来改善RBush JavaScript library中的批量插入性能(一种有效的R * -tree实现)。
答案 0 :(得分:1)
这是对问题的重述。您需要同时找到排名为M-1的元素,并使用它们将数组划分为M个未排序的组。
我建议从标准的quickselect开始,随机枢轴选择接近中位数(做随机子样本技巧来估计),每种情况下将数组分成2,也划分您需要在2中找到的排名元素列表。继续此操作,直到达到您在当前组中找到排名元素的级别。然后切换到quickselect的Floyd-Rivest变体以实际找到该元素并将当前组拆分为2.然后从快速选择中返回,您可以轻松地将所需的M组拼凑在一起。
此方法的预期运行时间为O(N log(M))
,且常量非常好。我怀疑这种情况明显好于可行。