用于插入大部分排序数据的数据结构,这些数据将维护排序顺序

时间:2012-07-02 18:26:01

标签: c++ algorithm optimization

这个名字说明了一切,但要详细说明我有一个带时间戳的向量列表。它们大部分都是排序的,但会有一些乱序值。我想以有序的方式输出它们,但是矢量将以流式传输进入,我不想大量缓冲,因为我想及时输出我的结果。

所以我想保留一个带有N个向量的“向前看”列表。当我在新的向量中读到时,我想将它插入到列表中,然后从列表顶部弹出最旧的向量到输出,这样列表就会保持一个常数N向量的长度。

当我插入列表时,我希望对矢量进行排序并添加到列表中的正确位置,因为我认为这是最有效的方法。

我需要很好的效率,但不想浪费太长时间的实施和测试。所以我对简单的解决方案(例如重用现有的C ++结构,如果它们存在)感兴趣,并且如果能够提供明显的速度提升,则更难实现解决方案。我更愿意坚持标准的C ++,但如果有一个提升或类似的库完全符合我的需要,我很乐意听到它以防万一。

谢谢。

编辑:我感谢所有建议。但是,我忽略了时间戳并不是唯一的。时间戳只有第二个精度,所以实际上我很可能得到具有相同时间戳的多个向量。在这种情况下,我宁愿保留他们的订单,尽管没有必要。

4 个答案:

答案 0 :(得分:3)

看一下std::multiset课程。

您应该检查其insert方法:

#include <set>
#include <functional>

const size_t max_item_number = 100;

struct your_type
{
  std::string str;
  time_t datetime;
};

class your_less : std::binary_function<your_type,your_type,bool>
{
public:
  bool operator()( const your_type &left, const your_type &right ) const
  {
    return ( left.datetime < right.datetime );
  }
};


std::multiset<your_type,your_less> store;
std::multiset<your_type,your_less>::iterator helper = store.begin();

helper = store.insert( helper, new_value );
helper = store.insert( helper, new_value );

// fixed size: remove the oldest value
// you could use it e.g. in loop
if ( store.size() == max_item_number )
{
  store.erase( store.begin() );
  helper = store.begin();
}

这样,如果订购了流,则插入时间可以保持不变。

答案 1 :(得分:1)

简单的选择: priority_queue O(lg n)插入和提取min,比set / multiset快很多(整数为3倍)并且占用内存较小

如果输入几乎已排序,则可以使用插入排序的某些变体。你只需要保留已排序的deque并将某些东西插回去,然后从前面弹出分钟。

答案 2 :(得分:0)

查看std::set课程。

答案 3 :(得分:0)

如果你是在一个大的缓冲区中做到这一点,那么Timsort会非常出色。它可以利用部分排序。但是你说你不需要那个。

如果你需要在循环内部保持可管理的东西,你最好使用treap或红黑树。

Treaps平均速度很快(我最近在许多不同的条件下对Python中的树数据结构进行了性能比较,发现treaps总是最快或者平均速度第二快 - 其他两个有时比treaps快一点取决于工作量,但不一定如此)

据报道,红黑树的运行时间较短,标准偏差较小(平均而言,它们比平均水平慢,但如果这是一个实时或交互式应用程序,那么红黑树的效果可能更低操作时间变化)。

相关问题