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

data structure for inserting mostly-sorted data which will maintain a sorted order

本文关键字:数据 排序 顺序 数据结构 插入 大部分 用于      更新时间:2023-10-16

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

所以我想保留一个包含 N 个向量的"展望"列表。 当我读入新向量时,我想将其插入到列表中,然后从列表顶部弹出最旧的向量进行输出,以便列表保持恒定的 N 向量长度。

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

我需要良好的效率,但不想浪费太长时间来实现和测试。 因此,我对简单的解决方案(例如重用现有的C++结构(如果存在))以及更难实现的解决方案感兴趣,如果它们可以显着提高速度。 我更愿意坚持使用标准C++,但如果有一个提升或类似的库可以完全满足我的需求,我很想听听它以防万一。

谢谢。

编辑:我感谢所有建议。 但是,我忽略了时间戳不是唯一的。 时间戳只有秒精度,因此实际上我很可能会获得具有相同时间戳的多个向量。 在这种情况下,我宁愿保留他们的顺序,尽管这不是必需的。

看看

std::multiset类。

您应该检查其插入方法:

#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();
}

这样,如果流是有序的,则插入时间可以是恒定的。

简单的选项:priority_queueO(lg n) 插入和提取最小值,比集合/多集快得多(整数为 3 倍),内存占用更小

如果输入几乎已排序,则可以使用插入排序的某些变体。您只需保持排序的deque并将内容插入后面的某个地方,然后从前面弹出分钟。

看看std::set类。

如果你在一个大缓冲区中用一个大排序来做,Timsort 会很棒。它能够利用部分排序。 但你说你不需要那个。

如果你需要事情在没有循环内部排序的情况下保持可管理性,你最好使用像 treap 或红黑色树这样的东西。

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

据报道,红黑树

给出的操作时间具有低标准偏差(与平均而言,它们有点慢,但如果这是一个实时或交互式应用程序,红黑树可能因其低操作时间可变性而更好)。