Data structures 使用动态和非唯一键存储大量数据的最佳数据结构?

Data structures 使用动态和非唯一键存储大量数据的最佳数据结构?,data-structures,Data Structures,基本上,我有大量的C结构需要跟踪,基本上是: struct Data { int key; ... // More data }; 我需要定期访问大量(数百个)这些,并且它们必须从最低到最高排序键值。这些键不是唯一的,它们将在程序过程中更改。为了让事情变得更有趣,大多数结构将在排序之前从池中剔除(基于与键值完全无关的标准),但我仍然需要保留对它们的引用 我已经研究过使用二叉搜索树来存储它们,但是密钥不能保证是唯一的,而且我也不完全确定一旦密钥被更改,如何重新构造树

基本上,我有大量的C结构需要跟踪,基本上是:

struct Data {
    int key;
    ...        // More data
};
我需要定期访问大量(数百个)这些,并且它们必须从最低到最高排序
值。这些键不是唯一的,它们将在程序过程中更改。为了让事情变得更有趣,大多数结构将在排序之前从池中剔除(基于与键值完全无关的标准),但我仍然需要保留对它们的引用

我已经研究过使用二叉搜索树来存储它们,但是密钥不能保证是唯一的,而且我也不完全确定一旦密钥被更改,如何重新构造树,或者如何挑选特定的结构

为了在上述不清楚的情况下进行总结,我需要:

  • 存储大量具有非唯一键和动态键的结构
  • 剔除大部分结构(但不能完全释放它们,因为每次都会剔除不同的结构)
  • 将其余结构从最高键值排序到最低键值
  • 您将使用什么数据结构/算法来解决此问题?该方法需要尽可能快和/或内存效率,因为这是一个实时应用程序


    编辑:剔除是通过对所有对象进行迭代并对每个对象进行决策来完成的。关键点在剔除/排序运行之间发生变化。我应该说它们变化不大,但它们确实发生了变化,而且它们可以在剔除/排序运行之间多次变化。(如果有帮助,每个结构的关键实际上是精灵的z顺序。它们需要在每个绘图循环之前进行排序,以便首先绘制z顺序较低的精灵。)

    此类问题的一般解决方案是使用平衡搜索树(例如AVL树、红黑树、B树),这保证了O(logN)时间(几乎不变,但不完全不变)用于插入、删除和查找,其中n是树中当前存储的项数。保证树中不存储两次密钥非常简单,许多实现都会自动完成

    如果你在C++中工作,你可以尝试使用<代码> STD::MAP< /Cord>。如果在C中找到或实现一些简单的二叉搜索树代码,看看它是否足够快。


    然而,如果你使用这样的树,发现它太慢,你可以研究一些更精细的方法。一种可能是将你的结构放在一个大数组中,按整数键,对它进行剔除,然后按过程重新排序。另一种方法可能是使用Patricia树。

    解决这类问题的一般方法是使用平衡搜索树(例如AVL树、红黑树、B树),它保证插入、删除和查找的时间为O(logn)(几乎不变,但不是完全不变),其中n是树中当前存储的项目数。保证树中不存储任何键两次是非常简单的,并且由许多实现自动完成

    如果你在C++中工作,你可以尝试使用<代码> STD::MAP< /Cord>。如果在C中找到或实现一些简单的二叉搜索树代码,看看它是否足够快。


    然而,如果你使用这样一个树,发现它太慢了,你可以研究一些更精细的方法。一种可能是将你的结构放在一个大数组中,按整数键,对它进行剔除,然后按过程重新排序。另一种方法可能是使用Patricia树。

    只需将它们都放在一个大数组中即可

    当需要进行剔除和排序时,从排序开始。做一个插入排序。这是正确的-没有什么聪明的,只是一个插入排序

    排序后,遍历已排序的数组,对每个对象做出剔除决策,如果未剔除,则立即输出该对象

    这与内存效率差不多。它还需要很少的计算:在剔除/排序过程之间没有更新的簿记,而且排序会很便宜——因为插入排序是自适应的,对于这样的几乎排序的数组,它几乎是O(n)。它没有做的一件事是缓存局部性:在数组上有两个单独的传递,分别用于排序和剔除/输出

    如果您需要更聪明的方法,那么可以使用另一种更快的自适应就地排序,而不是插入排序。Timsort和smoothsort都是很好的候选者;两者都非常难实现


    最大的替代方法是只对未填充的对象进行排序,使用排序(或保存在二叉树中)的二级临时对象列表。但问题是,如果键没有太大变化,那么在几乎排序的数组中使用自适应排序将获得胜利(我想!)超过排序较小数据集所获得的收益。这是O(n)vs O(n log n)。

    只需将它们全部放在一个大数组中即可

    当需要进行剔除和排序时,从排序开始。做一个插入排序。这是正确的-没有什么聪明的,只是一个插入排序

    排序后,遍历已排序的数组,对每个对象做出剔除决策,如果未剔除,则立即输出该对象

    这与内存效率差不多。它还需要很少的计算:在剔除/排序过程之间没有更新的簿记,而且排序会很便宜——因为插入排序是自适应的,对于这样的几乎排序的数组,它几乎是O(n)。它没有做的一件事是缓存局部性:在数组上有两个单独的传递,分别用于排序和剔除/输出

    如果您需要更聪明的方法,那么可以使用另一种更快的自适应就地排序,而不是插入排序。Timsort和smoothsort都是很好的候选者;两者都非常难实现

    最大的替代方法是只对未填充的对象进行排序