更新有序数字数组的最快方法是什么?

时间:2011-07-29 16:26:42

标签: algorithm sorting data-structures

我需要计算一个必须动态维护并经常查找的1d直方图。我的一个想法涉及保持有序数组与数据(因此我可以确定O(1)中的百分位数,这足以快速找到具有非均匀箱的直方图,每个箱内的点数完全相同)。

那么,是否有一种方法小于O(N)将数字插入有序数组中,同时保持其有序?

我想答案是众所周知的,但我对算法知之甚少(物理学家很少做数值计算)。

5 个答案:

答案 0 :(得分:3)

在一般情况下,您可以使用更灵活的树状数据结构。这将允许在O(log)时间内访问,插入和删除,并且相对容易从库中准备好(例如:C ++的STL映射)。

(或哈希地图......)

具有二进制搜索的有序数组与树相同,但更加严格。对于访问和内存使用来说可能会更快,但是当你必须在中间插入或删除东西时会付出代价(O(n)成本)。

但请注意,有序数组可能对您来说足够了:如果您的数据点通常相同,您可以保留按键排序的对{list,count}列表,能够快速添加另一个实例现有项目(但仍需要做更多工作来添加新项目)

答案 1 :(得分:1)

您可以使用二进制搜索。这是O(log(n))。 如果你想插入数字x,那么取数组中间的数字并将其与x进行比较。如果x小于那么则取上半部分中间的数字,然后取下半部分中间的数字,依此类推。

答案 2 :(得分:0)

  

那么,有没有一种方法可以小于O(N)来插入一个数字   有序数组,同时保持秩序?

是的,您可以使用数组来实现使用数组的binary search tree并在O(log n)时间内插入。怎么样?

保持索引0为空; index 1 = root;如果node是父节点的左子节点,则节点索引= 2 *父节点的索引;如果node是父节点的右子节点,则节点的索引= 2 *父节点的索引+ 1。

因此插入将是O(log n)。不幸的是,您可能会注意到,如果您不平衡树,即O(n),那么有序列表的二叉搜索树可能会退化为线性搜索,这是毫无意义的。在这里,您可能必须实施red black tree以保持高度平衡。但是,这非常复杂,但是可以使用O(log n)中的数组进行插入。请注意,数组元素将不再是整数;相反,它们必须是具有颜色属性的对象。

我不推荐它。

答案 3 :(得分:0)

如果您将数组重新排列为挂在每个元素上的一堆链接列表,则可以在O(1)时间内执行插入:

keys = Array([0][1][2][3][4]......)
              a  c  b  e  f  .  .
              d  g     i  .  .  .
                 h     j  .
              |__|__|__|__|__|__|__/linked lists

还有一种策略是同时保留两个数据结构,如果您的更新工作负载支持它,而不会增加常见操作的时间复杂性。

答案 4 :(得分:0)

这需要一个阵列?您需要一个数据结构,以保持数据的顺序,并允许您快速插入。为什么不是二叉搜索树?或者更好的是,一棵红黑树。在C ++中,您可以使用标准模板库中的Set结构,该模板库实现为红黑树。给你O(log(n))插入时间以及像数组一样迭代它的能力。