[STL]: explicación detallada del uso de la lista

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

1. Introducción a la lista

2. Uso de la lista

2.1 Definición de lista

2.2 Iterador

2.3 Crecimiento espacial

2.4 Acceso

2.5 Modificación 

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!  

Supongo que te gusta

Origin blog.csdn.net/Yikefore/article/details/134074502
Recomendado
Clasificación