我正在寻找一种数据结构(类似数组),允许快速(比O(N)更快)任意插入值到结构中。数据结构必须能够以插入方式打印出元素。这类似于List.Insert()(它太慢了,因为它必须移动每个元素),除了我不需要随机访问或删除。插入将始终在'数组'的大小范围内。所有值都是唯一的。不需要其他操作。
例如,如果Insert(x,i)在索引i(0-indexing)处插入值x。然后:
它最终需要能够打印出{5,1,2,3}。
我正在使用C ++。
答案 0 :(得分:9)
使用skip list。另一种选择应该是tiered vector。跳过列表在const O(log(n))执行插入并按顺序保存数字。分层向量支持插入O(sqrt(n))并再次按顺序打印元素。
编辑:根据amit的评论,我将解释如何在跳过列表中找到第k个元素:
对于每个元素,您在下一个元素的链接上都有一个塔,并且对于每个链接,您知道它跳过了多少个元素。因此,寻找第k个元素,从列表的头部开始,然后沿着塔向下走,直到找到跳过不超过k个元素的链接。您转到此节点指向的节点,并使用跳过的元素数减少k。继续这样做,直到你有k = 0。
答案 1 :(得分:1)
您考虑使用std::map
还是std::vector
?
您可以使用插入等级的std::map
作为关键字。 vector有一个reserve
成员函数。
答案 2 :(得分:1)
您可以使用std::map
映射(索引,插入时间)对值,其中inserted-time是“自动增量”整数(以SQL术语表示)。对的排序应该是
(i, t) < (i*, t*)
当且仅当
i < i* or t > t*
在代码中:
struct lt {
bool operator()(std::pair<size_t, size_t> const &x,
std::pair<size_t, size_t> const &y)
{
return x.first < y.first || x.second > y.second;
}
};
typedef std::map<std::pair<size_t, size_t>, int, lt> array_like;
void insert(array_like &a, int value, size_t i)
{
a[std::make_pair(i, a.size())] = value;
}
答案 3 :(得分:1)
关于你的评论:
List.Insert()(它太慢了,因为它必须移动每个元素),
列表不会移动它们的值,它们会迭代它们以找到您要插入的位置,请小心您的说法。这对像我这样的新手来说可能会让人感到困惑。
答案 4 :(得分:0)
默认情况下,GCC附带的解决方案是 rope 数据结构。这是documentation。通常,在处理长字符串时会想到绳索。这里我们有int
而不是字符,但它的工作方式相同。只需使用int
作为模板参数即可。 (也可能是pair
s等)
这是description of rope on Wikipedia。
基本上,它是一个二叉树,用于维护左右子树中有多少元素(或等效信息,即所谓的顺序统计),这些计数会相应更新为插入和删除元素时,子树会旋转。这允许O(lg n)操作。
答案 5 :(得分:-1)
在c ++中你可以使用矢量图,如下所示:
int main() {
map<int, vector<int> > data;
data[0].push_back(1);
data[1].push_back(3);
data[1].push_back(2);
data[0].push_back(5);
map<int, vector<int> >::iterator it;
for (it = data.begin(); it != data.end(); it++) {
vector<int> v = it->second;
for (int i = v.size() - 1; i >= 0; i--) {
cout << v[i] << ' ';
}
}
cout << '\n';
}
打印:
5 1 2 3
就像你想要的那样,插入是O(log n)。