// set::insert (C++98)
#include <iostream>
#include <set>
int main ()
{
std::set<int> myset;
std::set<int>::iterator it;
std::pair<std::set<int>::iterator,bool> ret;
// set some initial values:
for (int i=1; i<=5; ++i) myset.insert(i*10); // set: 10 20 30 40 50
ret = myset.insert(20); // no new element inserted
if (ret.second==false) it=ret.first; // "it" now points to element 20
myset.insert (it,25); // max efficiency inserting
myset.insert (it,24); // max efficiency inserting
myset.insert (it,26); // no max efficiency inserting
int myints[]= {5,10,15}; // 10 already in set, not inserted
myset.insert (myints,myints+3);
std::cout << "myset contains:";
for (it=myset.begin(); it!=myset.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
我在cplusplus参考站点上看到此代码为例。它说
myset.insert (it,25); // max efficiency inserting
myset.insert (it,24); // max efficiency inserting
这是插入效率的最大值,但我不明白。 谁能告诉我为什么?
答案 0 :(得分:3)
std::set
使用平衡树结构。当您致电insert
时,您可以提供实施提示 - 它可以用来加快插入速度。
考虑常规二进制搜索树中的常规insert
方法如何工作。从根节点开始,您必须使用常规检查进行降级:
void insert(node* current, const T& value)
{
if(node == nullptr) // Construct our new node here
else if(value < node->current) insert(current->left, value);
else if(value > node->current) insert(current->right, value);
}
void insert(const T& value)
{
insert(root, value);
}
在平衡树中,这必须执行(平均)O(log n)
比较以插入给定值。
但是,假设我们不是从根节点开始,而是为实现提供一个起始节点,该节点是实际插入发生的地方。例如,在上面,我们知道24和25将成为包含20
的节点的子节点。因此,如果我们从那个节点开始,我们不需要进行O(log n)
比较 - 我们可以直接插入我们的节点。这就是“最大效率”插入的意思。
答案 1 :(得分:0)
您是否阅读过通知?
位置 提示元素可以插入的位置。 C ++ 98 如果位置指向,则该函数优化其插入时间 插入元素之前的元素。
它指向20并且在25之前。
答案 2 :(得分:0)
通常,std::set
必须查找它插入的位置;这个
查找是O(lg n)。如果你提供“提示”(附加的
迭代器)插入应该发生的地方
实现将首先检查此提示是否正确(哪个
可以在O(1)中完成,如果是,则插入那里,从而跳过
O(lg n)向上看。如果提示不正确,当然,它
然后恢复到插入状态,好像它没有得到提示一样。
有两种情况经常使用提示:第一种
是在插入已排序数据的序列时。在
在这种情况下,提示是结束迭代器,因为如果数据是
已经排序,每个新值实际上将被插入
结束。第二种是使用插入复制到集合中
迭代器。在这种情况下,“提示”(可以是任何东西)
不仅仅是出于语法原因:你不能使用
back_insertion_iterator
或front_insertion_iterator
,
因为std::set
没有push_back
或push_front
,并且
简单的insertion_iterator
需要一个迭代器来告诉它
在哪里插入;此迭代器将传递给insert
。