Uno de los contenedores más útiles de la STL es
Vector.
Implementa un vector de elementos consecutivos en memoria. Permite la
adición de elementos (con coste O(1)), la inserción en cualquier punto
del vector (con coste O(n), claro), eliminación en cualquier punto del
vector (con coste O(n)), y el acceso a los elementos.
Un ejemplo de uso de la estructura de datos Vector es el siguiente:
#include <vector>
#include <iostream>
using namespace std;
void muestra(const vector<int> &v)
{
for(unsigned int i = 0; i < v.size(); ++i ) {
cout << v[ i ] << endl;
}
}
int main()
{
vector<int> s;
s.push_back( 1 );
s.push_back( 2 );
s.push_back( 3 );
muestra( v );
}
size() devuelve el número de elementos en un vector.
Pero para recorrer un vector, es posible emplear también iteradores (
iterators).
Los iteradores son como punteros, pero encapsulan gran parte de su
comportamiento, de manera que sean más sencillos de usar. Los
iteradores siempre son de un acceso mucho más rápido que el operador [].
void muestraRapida(const vector<int> &v)
{
vector<int>::const_iterator it = v.begin();
while( it != v.end() ) {
cout << *it << endl;
++it;
}
}
Los iteradores constantes (
const_iterators),
sólo tienen permitido acceder a un elemento (mediante el operador *)
para leerlo, pero no para modificarlo. Si queremos sumar uno a todos
los elementos del vector:
void sumaUno(vector<int> &v)
{
vector<int>::iterator it = v.begin();
while( it != v.end() ) {
++(*it);
++it;
}
}
[Sólo frikies]También se puede hacer en plan "resumido", como:
void sumaUno(const vector<int> &v)
{
vector<int>::iterator it = v.begin();
while( it != v.end() ) ++(*it++);
}
[/Sólo frikies]
La listas de la STL se crean mediante el encabezado (contenedor) list.
Para poder recorrerla, sólo se pueden usar iteradores. Hay un método
size(), pero es O(n), ya que necesita recorrer toda a lista para ir
contando los elementos. A cambio, todas las operaciones (inserción,
borrado ... etc.) son O( 1 ), excepto el acceso, que es secuencial, y
por tanto O(i), siendo i el elemento al que deseamos acceder.
#include <iostream>
#include <list>
using namespace std;
void muestra(const list<int> &l)
{
list::const_iterator it = l.begin();
while( it != l.end() ) {
cout << *it << endl;
++it;
}
}
int main()
{
list<int> l;
l.insert( l.end(), 1 ); // { 1 }
l.insert( l.end(), 2 ); // { 1, 2 }
l.insert( l.begin(), 3 ); // { 3, 1, 2 }
muestra( l );
}
A
veces es interesante acceder al elemento i de la lista. Para ello,
contamos con advance(), en la cabecera utility, que permite hacer
avanzar un iterador fácilmente. Nótese que las listas están enlazadas
hacia delante y hacia atrás, así que es posible hacer tanto --it como
++it.
#include <utility>
usigned namespace std;
int main()
{
typedef list<int> ListaNumeros;
typedef ListaNumeros::iterator ItListaNumeros;
ListaNumeros l;
ItListaNumeros it;
l.insert( l.end(), 1 );
l.insert( l.end(), 2 );
l.insert( l.end(), 3 );
it = l.begin();
advance( it, 2 );
l.insert( it, 33 );
advance( it, -1 ); // ó "--it;"
l.insert( l.end(), 22 );
muestra( l );
}
Como se puede ver, muchas veces se puede emplear
typedef para hacer más sencillo el manejo de plantillas.