Amigos y muchachos, nos volvemos a encontrar. En este número les explicaré el uso de las listas. Si les inspira después de leerlo, dejen sus comentarios. ¡Deseo que todos sus deseos se hagan realidad!
Columna de lenguaje C:Lenguaje C: de principiante a maestro
Columna de estructura de datos:Estructura de datos
Número principal de persona:stackY,
C + + Descripción:C++
Linux 专 栏:Linux
Tabla de contenido
3. El iterador de la lista no es válido.
1. Introducción a la lista
enumerar la referencia del documento oficial
Similar a mencionada en la estructura de datosLista enlazada circular con encabezado bidireccional
- 1. La lista es un contenedor secuencial que se puede insertar y eliminar en cualquier posición dentro del rango constante, y el contenedor se puede iterar hacia adelante y hacia atrás en ambas direcciones.
- 2. La capa inferior de la lista es una estructura de lista doblemente enlazada. Cada elemento de la lista doblemente enlazada se almacena de forma independiente. Nodo que no está relacionado entre sí. El nodo apunta a su elemento anterior y al siguiente mediante punteros.
- 3. List es muy similar a forward_list: la diferencia principal es que forward_list es una lista enlazada individualmente, solo puede iterar hacia adelante y Se ha permitido que sea más sencillo y eficiente.
- 4. En comparación con otros contenedores secuenciales (matriz, vector, deque), list generalmente funciona mejor al insertar y eliminar elementos en cualquier posición.
- 5. En comparación con otros contenedores secuenciales, el mayor defecto de list y forward_list es que no admiten acceso aleatorio en ninguna ubicación, Por ejemplo: para acceder al sexto elemento de la lista, debe iterar desde una posición conocida (como la cabeza o la cola) hasta esa posición. Iterar en esta posición requiere una sobrecarga de tiempo lineal; la lista también requiere algo de espacio adicional para guardar cada elemento. Información asociada con los nodos (este puede ser un factor importante para listas grandes que almacenan elementos más pequeños)
2. Uso de la lista
la lista debe aprenderse al estudiarVer documentos:lista de referencia de documentos oficiales< a i = 4>, la lista es muy importante en la práctica. En la práctica, solo necesitamos estar familiarizados con las interfaces comunes. A continuación se enumeran en qué interfaces debemos centrarnos.
2.1 Definición de lista
Constructor ((constructor)) | Descripción de la interfaz |
lista (tipo_tamaño n, tipo_valor constante y val = tipo_valor()) | La lista construida contiene n elementos con el valor val. |
lista() | Construir una lista vacía |
lista (lista constante y x) | constructor de copias |
lista (InputIterator primero, InputIterator último) | Construya una lista con elementos en el rango [primero, último) |
Antes de usar la lista, debe incluir el archivo de encabezado correspondiente a la lista:#include <list>
void list_test1() { //空构造 list<int> lt1; //n个val list<string> lt2(10, "0x0"); //迭代器区间 vector<int> v = { 0,1,2,3,4,5,6,7,8,9 }; list<int> lt3(v.begin() + 2, v.end()); //拷贝构造 list<string> lt4(lt2); }
2.2 Iterador
declaración de función | Descripción de la interfaz |
comienzo + fin |
Devuelve un iterador al primer elemento + un iterador a la siguiente posición del último elemento |
rbegin + render |
Devuelve el iterador_inverso del primer elemento, que es la posición final, y devuelve la siguiente posición del último elemento iterador_inverso, que es la posición inicial |
void list_test2() { list<int> lt; lt.push_back(1); lt.push_back(2); lt.push_back(3); lt.push_back(4); //正向迭代器 list<int>::iterator it = lt.begin(); //auto it = lt.begin(); while (it != lt.end()) { cout << *it << " "; it++; } cout << endl; //反向迭代器 list<int>::reverse_iterator rit = lt.rbegin(); //auto rit = lt.rbegin(); while (rit != lt.rend()) { cout << *rit << " "; rit++; } cout << endl; //范围for for (auto e : lt) { cout << e << " "; } cout << endl; }
2.3 Crecimiento espacial
declaración de función | Descripción de la interfaz |
vacío | Compruebe si la lista está vacía; devuelva verdadero si está vacía; de lo contrario, devuelva falso |
tamaño | Devuelve el número de nodos válidos en la lista. |
void list_test3() { list<int> lt; lt.push_back(1); lt.push_back(2); lt.push_back(3); lt.push_back(4); cout << lt.empty() << endl; size_t sz = lt.size(); cout << sz << endl; }
2.4 Acceso
declaración de función | Descripción de la interfaz |
frente | Devuelve una referencia al valor en el primer nodo de la lista. |
atrás | Devuelve una referencia al valor en el último nodo de la lista. |
void list_test4() { list<int> lt; lt.push_back(1); lt.push_back(2); lt.push_back(3); lt.push_back(4); cout << lt.front() << endl; cout << lt.back() << endl; }
2.5 Modificación
declaración de función | Descripción de la interfaz |
empujar_frontal | Insertar un elemento con valor val antes del primer elemento de la lista |
pop_front | Eliminar el primer elemento de la lista. |
hacer retroceder | Insertar un elemento con valor val al final de la lista |
pop_back | Eliminar el último elemento de la lista. |
insertar | Insertar un elemento con valor val en la posición de la lista |
borrar | Eliminar el elemento en la posición de la lista |
intercambio | Intercambiar elementos en dos listas |
claro | Borrar elementos válidos en la lista. |
void list_test5() { list<int> lt; lt.push_back(1); lt.push_back(2); lt.push_back(3); lt.push_back(4); //头插 lt.push_front(0); //尾插 lt.push_back(5); //头删 lt.pop_front(); //尾删 lt.pop_back(); //pos位置插入 list<int>::iterator lit = lt.begin(); ++lit; lt.insert(lit, 30); //在pos位置插入n个数据 --lit; lt.insert(lit, 2, 10); //迭代器区间插入 vector<int> v = { 10,20 }; ++lit; lt.insert(lit, v.begin(), v.end()); //范围for for (auto e : lt) { cout << e << " "; } cout << endl; }
void list_test6() { list<int> lt; lt.push_back(1); lt.push_back(2); lt.push_back(3); lt.push_back(4); list<int>::iterator lit1 = lt.begin(); //删除pos位置 lt.erase(lit1); //删除一段迭代器区间 lt.erase(lt.begin(), lt.end()); //范围for for (auto e : lt) { cout << e << " "; } cout << endl; }
void list_test7() { list<int> lt1; lt1.push_back(1); lt1.push_back(2); lt1.push_back(3); lt1.push_back(4); list<int> lt2; lt2.push_back(4); lt2.push_back(3); lt2.push_back(2); lt2.push_back(1); //交换 lt1.swap(lt2); //清理 lt1.clear(); lt2.clear(); }
3. El iterador de la lista no es válido.
Como se mencionó anteriormente, el iterador puede entenderse temporalmente como similar a un puntero.La falla de un iterador significa que el nodo al que apunta el iterador no es válido, es decir, el nodo ha sido eliminado. . Debido a que la estructura subyacente de la lista es una lista enlazada circular bidireccional con el nodo principal, la inserción en la lista no provocará que falle el iterador de la lista. Solo se invalidará cuando se elimine, y solo se invalidará el iterador que apunta al nodo eliminado, otros iteradores no se verán afectados.
(Los detalles específicos se explicarán durante la implementación de la simulación)void list_test8() { list<int> lt1; lt1.push_back(1); lt1.push_back(2); lt1.push_back(3); lt1.push_back(4); auto lit = lt1.begin(); while (lit != lt1.end()) { lt1.erase(lit); // erase()函数执行后,it所指向的节点已被删除, // 因此it无效,在下一次使用it时,必须先给其赋值 lit++; } }
Escritura corregida:
void list_test8() { list<int> lt1; lt1.push_back(1); lt1.push_back(2); lt1.push_back(3); lt1.push_back(4); auto lit = lt1.begin(); while (lit != lt1.end()) { lit = lt1.erase(lit); //或者 //lt1.erase(lit++); lit++; } }
Amigos y chicos, los buenos momentos siempre son cortos. Nuestro intercambio en este número termina aquí. Si quieren saber qué sucede a continuación, escuchen el próximo episodio ~. No olviden dejarles preciosos después de leerlo. Gracias por ¡tu apoyo!