我一直在寻找一些简单的实施数据结构,可以在最短的时间内完成我的需求(在最糟糕的情况下): -
(1)弹出第n个元素(我必须保持元素的相对顺序不变)
(2)访问第n个元素。
我无法使用数组,因为它无法弹出,我不想在删除ith元素后有间隙。我试图通过将下一个元素与下一个元素交换到下一个直到最后来消除间隙,但这证明时间无效,尽管数组的O(1)是无与伦比的。
我尝试使用vector并使用'erase'作为弹出窗口并使用'.at()'进行访问,但即使这样也不便宜,因为它比数组更好。
答案 0 :(得分:3)
您可以尝试的是skip list - 它支持您在O(log(n))中请求的操作。另一个选项是tiered vector,它实现起来稍微容易一点,需要O(sqrt(n))。这两种结构都非常酷,但不太受欢迎。
答案 1 :(得分:3)
嗯,在阵列上实现的分层向量我觉得最适合你的目的。虽然分层矢量概念可能一开始就知道并且有点难以理解但是一旦你得到它,它就会产生很多问题,你会得到一个方便的武器来非常有效地解决许多问题的数据结构部分。 因此建议您掌握分层向量实现。
答案 2 :(得分:2)
数组将为您提供O(1)
查找,但O(n)
删除该元素。
列表将为您提供O(n)
查找错误O(1)
删除元素。
二进制搜索树将为您O(log n)
查找O(1)
删除元素。但它并没有保留相对顺序。
与列表结合使用的二叉搜索树将为您提供两全其美的优势。将节点插入列表(以保留顺序)和树(快速查找)。删除将为O(1)
。
struct node {
node* list_next;
node* list_prev;
node* tree_right;
node* tree_left;
// node data;
};
请注意,如果使用索引作为排序值将节点插入树中,您将最终得到另一个假装为树的链接列表。 tree can be balanced however in O(n)
时间一旦建成,你只需要承担一次。
<强>更新强>
考虑到这一点,这可能不是最好的方法。我习惯于对数据本身进行查找而不是在集合中的相对位置。这是一种以数据为中心的方法。删除节点后,使用索引作为排序值将会中断,因为“更高”的索引需要更改。
答案 3 :(得分:0)
警告:不要认真对待这个答案。
理论上,你可以在O(1)中做到这两点。假设这是您要优化的唯一操作。以下解决方案将需要大量空间(并且它将泄漏空间),并且创建数据结构需要很长时间:
使用数组。在数组的每个条目中,指向另一个相同的数组,但删除了该条目。