增加元素
为了增加元素,两种容器都提供了insert方法,该方法支持在特定的位置加入新的元素。在STL中位置一般用迭代器指定:
这里添加代码
int ary1[5] = {1, 2, 3, 4, 5}; // 整型数组
vector<int> vec(ary1, ary1+5); // 用数组初始化向量
vector<int>::iterator iter = vec.begin() + 2;
// 定义迭代器,指向容器 vec 的第三个元素
vec.insert( iter, 6 ); // 在 vec 的第三个元素处插入一个新元素 6
set<int> intSet( vec.begin(), vec.end() ); // 构造一个整型数集合
set<int>::iterator iter = intSet.begin() + 2; // 集合的迭代器,指向第三个元素
intSet.insert( iter, 7 ); // 在集合的第三个元素处插入一个新元素 7
由于在序列式容器中,相邻两个元素的存储单元存在先后关系,插入元素时要维护这段关系。所以,对于连续存储的容器,要移动插入位置后面的元素;对于链式存储的容器,要建立新的连接关系。连续存储的容器,如果其容量不能满足数据插入的需求,则应当重新分配足够大的内存复制原来的数据,并插入新值。。在上述例子中,向量中插入数据的效果如图所示。
?关联式容器插入数据的效果
关联式容器插入数据的效果和序列式容器插入数据的效果是不同的。由于关联式容器是自动排序的,插入的元素会按照其键值的大小放置到合适的地方,所以关联式的容器并不会再期望的地方插入元素,其传入的迭代器只能作为参考。
?其他增加元素的方法
除了insert方法,序列式容器还提供了压入(push)方法,根据容器的不同,分别使用push_back, push_front, push方法。压入元素没有insert操作那么灵活,而只能在容器头或者容器尾操作,例如:
这里添加代码
vector<int> vec(); // 声明一个向量
vec.push_back( 1 ); // 压入数据
vec.push_back( 2 );
list<int> ls(); // 声明一个链表
ls.push_back( 1 ); // 压入数据
ls.push_front( 2 );
stack<int> st(); // 声明一个栈
st.push( 1 ); // 压入数据
st.push( 2 );
流程图:
删除元素
为了删除元素,两种容器都提供了erase方法,改方法支持删除指定位置、指定区间的元素。另外,也可以用clear方法,删除容器中的所有元素。对于关联式容器,还可以删除指定键值的元素。当然,删除数据之后,应当对容器的存储结构进行重新组织,以保证结构的完整性。列如:
这里添加代码
int ary1[6] = {1, 2, 3, 4, 5, 6}; // 整型数组
vector<int> vec(ary1, ary1+6); // 用数组初始化向量
vector<int>::iterator iter = vec.begin() + 2;
// 定义迭代器,指向容器 vec 的第三个元素
vec.erase( iter ); // 删除第三个元素
ter = vec.begin() + 2; // 定义迭代器,指向容器 vec 的第三个元素
vec.erase( iter, vec.end() ); // 删除第二个元素之后的所有元素
set<int> intSet( ary1, ary1+5 ); // 构造一个集合
set.erase( 4 ); // 删除键值为 4 的元素(集合的键值与实值是一致的)
流程图:
查找元素
并不是所有容器都提供了专门的查找方法。序列式容器由于其存储结构的限制(未排序),查找效率较低,所以没有提供查找方法。而关联式容器在创建时就排好了序,插入元素时也会自动排序,所以非常适合查找。因此,关联式容器提供了专门的查找方法find,其参数是元素的键值,返回值是指向目标元素的迭代器。
对于序列式容器,可以使用某些特殊的方法来查找特定的元素。例如有的元素重载了下标运算符“[]”,给出索引就可以找到对应的元素,这一点类似数组。也可以通过成员函数at实现相同的功能。另外,序列式容器普遍都有front和back方法,用来返回第一个和最后一个元素,栈是个例外,只有函数top用来返回栈顶元素。例如:
这里添加代码
int ary1[6] = {1, 2, 3, 4, 5, 6}; // 整型数组
vector<int> vec(ary1, ary1+6); // 用数组初始化向量
int x = vec[ 3 ]; // 查找向量中的第三个元素
list<int> intList( vec.begin(), vec.end() ); // 构造链表
x = intList.front(); // 查找链表中的第一个元素
x = intList.back(); // 查找链表中的最后一个元素
stack<int,vector<int> > st; // 构造栈
……
x = st.top(); // 查找栈顶元素
修改元素
若要修改元素,则必须先查早到元素。如果查找到的结果是容器中元素的引用,则可以直接对该引用赋值。如果查找到的结果是指向容器中元素的迭代器,则可以通过迭代器的方法修改元素的值。例如:
这里添加代码
int ary1[6] = {1, 2, 3, 4, 5, 6}; // 整型数组
vector<int> vec(ary1, ary1+6); // 用数组初始化向量
vec[3] = 7; // []返回的是向量元素的引用
int &x = vec[3];
x = 7; // 效果与第 3 行相同
stack<int,vector<int> > st; // 构造栈
……
st.top() = x; // 修改栈顶元素
int &y = st.top(); // 查找栈顶元素
y = x; // 效果等同于第 8 行
map<int, int> intMap(); // 构造映射
……
map<int, int>::iterator iter = intMap.find( 5 ); // 查找键值为 5 的元素
iter->second = 3; // 将该元素的实值修改为 3
map[5] = 3; // 效果与第 12 行和第 13 行相同