Otros contenedores secuenciales de la STL en C++ Programación Orientada a Objeto Ing. Civil en Telecomunicaciones Otros contenedores secuenciales de la STL • Contenedores secuenciales forward_list (C++11) array (C++11) deque queue priority_queue stack Contenedor forward_list Contenedor forward_list • Especialización del contenedor list • Lista encadenada simple • Sólo se puede recorrer hacia adelante Elemento sólo contiene información necesaria para encontrar el siguiente elemento • Más eficiente que list, pero sólo acepta iteradores hacia adelante Agregada en C++11 Definida en <forward_list> Contenedor forward_list • Cómo insertar un elemento al comienzo de la lista, si no se puede recorrer hacia atrás? Contenedor forward_list incluye métodos before_begin() y cbefore_begin() que retornan un iterador a antes del primer elemento de la lista Ese iterador puede usarse luego con insert_after(), etc. © 2015 Mario Medina C. No contiene función miembro size() Tamaño de una forward_list se obtiene usando distance(fl.begin(), fl.end()) Contiene miembros insert_after(), erase_after(), push_front(), pop_front(), emplace_front() No contiene miembros push_back(), pop_back(), back() Ejemplo de uso #include <forward_list> #include <iostream> forward_list<int> fl = {13, 25, 52, 90}; fl.erase_after(fl.before_begin()); fl.push_front(10); fl.insert_after(fl.before_begin(), 1); for(int& x: fl) { cout << ' ' << x; } cout << endl; // Imprime 1, 10, 25, 52, 90 1 Contenedor array Contenedor array • Contenedor secuencial de tamaño fijo dado • Almacena datos secuencialmente en memoria • Diseñado para ser eficiente en términos de memoria y procesamiento • Introducido en C++11 • Equivalente a un vector de C • Acceso a elementos mediante [], at(), front(), back(), data() • No contiene funciones miembros para modificar su contenido Ejemplo de uso Contenedor deque #include <array> #include <cstring> #include <iostream> const char* cstring = "Test"; array<int, 4> a_int; array<char, 5> a_char; a_int.fill(10); for(int& x: a_int) { cout << ' ' << x; } cout << endl; // Imprime 10, 10, 10, 10 memcpy(a_char.data(), cstring, 5); cout << a_char.data() << endl; // Imprime "Test“ • No contiene miembros insert(), erase(), push_back(), etc. • Objetos array pueden tener tamaño 0 • Contenedor que implementa una cola FIFO (First-In, First-Out) bidireccional • Elementos pueden agregarse y retirarse de ambos extremos de la cola push_back() pop_front() pop_back() push_front() back() front() Contenedor deque Contenedor deque • Similar a vector • Objetos deque tienen tamaño dinámico, y permiten acceso aleatorio a sus elementos • Eficientes para inserción y borrado en los extremos Inserción y borrado eficiente en ambos extremos • No garantiza almacenamiento contiguo de los elementos en memoria Bloques de memoria disjuntos Tiempo de acceso aleatorio uniforme Menos eficientes que list y forward_list para inserción y borrado en otras posiciones Interfaz secuencial uniforme vía iteradores © 2015 Mario Medina C. 2 Ejemplo de uso Contenedor deque • Metodos son similares a vector y list [] , at() , front() , back() Posee métodos push_back(), pop_back(), push_front(), pop_front(), erase(), insert(), assign(), size(), empty(), resize(), etc. Acceso a elementos mediante #include <deque> #include <iostream> deque<int> dq; dq.push_front(5); dq.push_back(10); dq.insert(dq.begin(), 3); for(int& x: dq) { cout << ' ' << x; } cout << endl; // Imprime 3, 5, 10 Contenedor queue Contenedor queue • Contenedor que implementa una cola FIFO (First-In, First-Out) • Contenedor queue es un container adaptor, que es una forma de especialización de otro contenedor • En la STL, contenedor queue puede ser creado a partir de una list o un deque Elementos se insertan en un extremo de la cola y se extraen del otro extremo Declarada en <queue> push() pop() back() front() Contenedor queue • Método front() retorna el primer elemento de la cola • Método back() retorna el último elemento agregado • Método push() agrega un elemento • Método pop() retira un elemento • Método front() retorna el siguiente elemento © 2015 Mario Medina C. Por omisión, se usa un deque #include <queue> queue<int> q1; // Usa deque queue<int, list<int> > q2; Ejemplo de uso #include <queue> queue<int> q; q.push(10); q.push(20); q.push(30); cout << q.front() << ´ ´; q.pop(); q.back() = 77; q.front() = 4; while(!q.empty()) { cout << q.front() << ´ ´; q.pop(); } cout << endl; // Imprime 30 4 77 3 Contenedor priority_queue Contenedor priority_queue • Contenedor que implementa una cola de prioridades • Contenedor priority_queue también es un container adaptor • En la STL, contenedor priority_queue puede ser creado a partir de un vector o un deque Elementos se insertan en un extremo de la cola y se extraen del otro extremo Por omisión, el siguiente elemento es el de mayor prioridad Por omisión, se usa un deque Declarada en <queue> push() pop() top() #include <queue> priority_queue<int> pq1; // Usa deque priority_queue<int, vector<int> > pq2; Contenedor priority_queue Contenedor priority_queue • Ordenamiento por omisión utiliza el operador ´<´ • Es posible entregar como argumento una función o un function object a ser usado como operación de comparación • Interfaz básica priority_queue<float, std::greater<float> > prio; Ordena de menor a mayor Ejemplo de uso #include <queue> priority_queue<int> pq; pq.push(1); pq.push(5); pq.push(3); cout << pq.top() << ‘ ‘; pq.push(8); pq.push(4); while(!pq.empty()) { cout << pq.top() << ‘ ‘; pq.pop(); } cout << endl; // imprime 5 8 5 4 3 1 © 2015 Mario Medina C. push(): inserta un elemento pop(): remueve el siguiente elemento en orden de prioridad de la cola top(): retorna el siguiente elemento de la cola en orden de prioridad, pero no lo remueve size(): retorna el número de elementos empty(): retorna true si la cola está vacía Contenedor stack • Contenedor que implementa una pila, o cola de tipo LIFO (Last-In, First-Out) Elementos se insertan en un extremo de la pila y se extraen del mismo extremo Declarada en <stack> pop() top() push() 4 Contenedor stack Contenedor stack • Contenedor stack también es un container adaptor • En la STL, stack puede ser creado a partir de un vector, una list o un deque • Interfaz básica Por omisión, se usa un deque #include <stack> stack<int> st1; // Usa deque stack<int, list<int> > st2; Stack<string, vector<string> > st3; Ejemplo de uso #include <stack> stack<int> st; st.push(1); st.push(2); cout << st.top() << ´ ´; st.pop(); st.top() = 77; st.push(4); while(!st.empty()) { cout << st.top() << ´ ´; st.pop(); } cout << endl; // Imprime 2 4 77 © 2015 Mario Medina C. push(): inserta un elemento en la pila pop(): remueve un elemento de la pila, pero no lo retorna top(): retorna el siguiente elemento de la pila, pero no lo remueve size(): retorna el número de elementos en la pila empty(): retorna true si la pila está vacía Otros detalles • Para pilas y colas, los comportamientos de top() y pop() ante un contenedor vacío no están definidos • La comparación de contenedores está definida para pilas y colas, pero no para colas de prioridad Dos pilas o colas son iguales si tienen el mismo número de elementos y éstos están en el mismo orden 5