Pila y cola STL de C++

Tabla de contenido

1. Introducción a la pila

 Dos, uso de pila

3.implementación de simulación de pila

Versión normal:

Versión del adaptador:

Cuatro, introducción a la cola

Cinco, uso de colas

Seis.Implementación de simulación de cola

7.deque introducción

1. Adaptador de contenedor

2. Una breve introducción a deque

3. El defecto del deque

4. ¿Por qué elegir deque como contenedor predeterminado subyacente de pila y cola?


1. Introducción a la pila

pila------referencia

Primero, la pila es un adaptador de contenedor, que se usa especialmente en el entorno de contexto con operación de último en entrar, primero en salir, y su eliminación solo puede insertar y extraer elementos de un extremo del contenedor.
2. La pila se implementa como un adaptador de contenedor, que encapsula una clase específica como su contenedor subyacente y proporciona un conjunto de funciones miembro específicas para acceder a sus elementos, utilizando una clase específica como su contenedor subyacente específico del elemento La cola (es decir, la parte superior de la pila) se empuja y se abre.
3. El contenedor subyacente de la pila puede ser cualquier plantilla de clase de contenedor estándar o algunas otras clases de contenedor específicas, y estas clases de contenedor deben admitir las siguientes operaciones:

  • vacío: juicio de operación vacía
  • atrás: Obtener la operación del elemento de cola
  • push_back: operación de elemento de inserción de cola
  • pop_back: operación de eliminación de elemento de cola

4. Los contenedores estándar vector, deque y lista cumplen con estos requisitos. De forma predeterminada, si no se especifica ningún contenedor subyacente específico para la pila, se utiliza deque de forma predeterminada.

 Dos, uso de pila

función descriptiva Descripción de la interfaz
pila() construir una pila vacía
vacío() Compruebe si la pila está vacía
tamaño() Devuelve el número de elementos de la pila.
arriba() Devuelve una referencia al elemento superior de la pila.
empujar() Empuje el elemento val en la pila
estallido() Pop el elemento al final de la pila.

3.implementación de simulación de pila

Versión normal:

La implementación de simulación de la pila es muy sencilla, podemos utilizar el vector que hemos aprendido para encapsular varias de sus interfaces.

	template<class T>
	class Stack
	{
	public:
		Stack()
		{}

		const T& top()
		{
			return _v.back();
		}

		void pop()
		{
			return _v.pop_back();
		}

		void push(const T& val)
		{
			_v.push_back(val);
		}

		size_t size()
		{
			return _v.size();
		}

		bool empty()
		{
			return _v.empty();
		}
	private:
		vector<T> _v;
	};
    
    int main()
    {
	    Stack<int> st;
	    st.push(100);
	    st.push(200);
	    st.push(300);
	    st.push(400);

	    while (!st.empty())
	    {
		    cout << st.top()<<" ";
		    st.pop();
	    }
        return 0;
    }

 Aquí usamos el contenedor subyacente hecho de vector. En std::stack, el contenedor subyacente es deque y admite el cambio a otros contenedores, razón por la cual la pila se llama adaptador de contenedor.

Versión del adaptador:

Adaptador de contenedor, solo necesitamos usar un parámetro de plantilla de clase, un parámetro de plantilla de clase puede controlar el tipo de contenedor del almacenamiento de datos subyacente, ya sea vector, lista o deque.

    //容器适配器class Container = vector<T>,class Container = list<T>....
    template<class T ,class Container >
	class Stack
	{
	public:
		Stack()
		{}

		const T& top()
		{
			return _v.back();
		}

		void pop()
		{
			return _v.pop_back();
		}

		void push(const T& val)
		{
			_v.push_back(val);
		}

		size_t size()
		{
			return _v.size();
		}

		bool empty()
		{
			return _v.empty();
		}
	private:
		Container _v;
	};

    int main()
    {
	    Stack<int,list<int>> st;
	    st.push(100);
	    st.push(200);
	    st.push(300);
	    st.push(400);

	    while (!st.empty())
	    {
		    cout << st.top()<<" ";
		    st.pop();
	    }
        return 0;
    }

En la plantilla de clase, también se pueden proporcionar parámetros predeterminados para implementar el contenedor de almacenamiento predeterminado.

template<class T ,class Container = deque<T>>

Cuatro, introducción a la cola

cola-----referencia

1. Una cola es un adaptador de contenedor diseñado para operar en un contexto FIFO (primero en entrar, primero en salir), donde los elementos se insertan desde un extremo del contenedor y se extraen por el otro extremo.
2. La cola se implementa como un adaptador de contenedor. El adaptador de contenedor encapsula una clase de contenedor específica como su clase de contenedor subyacente. La cola proporciona un conjunto de funciones miembro específicas para acceder a sus elementos. Los elementos ingresan a la cola desde la cola y salen de la cola desde la cabecera.
3. El contenedor subyacente puede ser una de las plantillas de clase de contenedor estándar u otras clases de contenedor especialmente diseñadas. El contenedor subyacente deberá soportar al menos las siguientes operaciones:

  • vacío: comprueba si la cola está vacía
  • tamaño: devuelve el número de elementos válidos en la cola
  • front: Devuelve una referencia al elemento frontal de la cola
  • back: devuelve una referencia al elemento al final de la cola
  • push_back: ingresa a la cola al final de la cola
  • pop_front: fuera de la cola al principio de la cola

4. Las clases de contenedores estándar deque y list satisfacen estos requisitos. De forma predeterminada, si no se especifica ninguna clase de contenedor para la creación de instancias de cola, se utiliza la deque de contenedor estándar. 

Cinco, uso de colas

declaración de función Descripción de la interfaz
cola() construir una cola vacía
vacío() Compruebe si la cola está vacía, devuelva verdadero; de lo contrario, devuelva falso
tamaño() Devuelve el número de elementos válidos en la cola.
frente() Devuelve una referencia al elemento al principio de la cola.
atrás() Devuelve una referencia al elemento al final de la cola.
empujar() Poner en cola el elemento val al final de la cola
estallido() Quitar de la cola el elemento al principio de la cola.

Seis.Implementación de simulación de cola

Debido a que hay eliminación de encabezados e inserción de colas en la interfaz de la cola, es demasiado ineficiente usar vectores para encapsular, por lo que la cola se puede simular usando la lista, de la siguiente manera:

Versión de lista común:

    template<class T>
	class Queue
	{
	public:
		Queue()
		{
		}

		void push(const T& val)
		{
			_q.push_back(val);
		}

		void pop()
		{
			_q.pop_front();
		}

		const T& front()
		{
			return _q.front();
		}

		const T& back()
		{
			return _q.back();
		}

		size_t size()
		{
			return _q.size();
		}

		bool empty()
		{
			return _q.empty();
		}

	private:
		list<T> _q;
	};

Versión del adaptador:

    template<class T,class Container=list<T>>
	class Queue
	{
	public:
		Queue()
		{
		}

		void push(const T& val)
		{
			_q.push_back(val);
		}

		void pop()
		{
			_q.pop_front();
		}

		const T& front()
		{
			return _q.front();
		}

		const T& back()
		{
			return _q.back();
		}

		size_t size()
		{
			return _q.size();
		}

		bool empty()
		{
			return _q.empty();
		}

	private:
		Container _q;
	};

 7.deque introducción

1. Adaptador de contenedor

Un adaptador es un patrón de diseño (un patrón de diseño es un conjunto de uso repetido, conocido por la mayoría de la gente, clasificado y catalogado, y un resumen de la experiencia de diseño de código), que convierte la interfaz de una clase en otra interfaz que los clientes desean.

La estructura subyacente de pila y cola en la biblioteca estándar STL:

Aunque los elementos también se pueden almacenar en pila y cola, no se dividen en rangos de contenedores en STL, sino que se denominan adaptadores de contenedor, porque las pilas y colas solo envuelven las interfaces de otros contenedores, STL En pila y cola, se usa deque por defecto, por ejemplo:

2. Una breve introducción a deque

Deque (cola de doble extremo): es una estructura de datos espaciales "continua" de doble apertura. El significado de doble apertura es: la inserción y eliminación se pueden realizar en ambos extremos de la cabeza y la cola, y la complejidad del tiempo es O (1) En comparación con el vector, la eficiencia del complemento es alta y no es necesario mover elementos; en comparación con la lista, la tasa de utilización del espacio es relativamente alta.

 Al mismo tiempo, a juzgar por la interfaz proporcionada en la biblioteca, deque también proporciona la función de acceso aleatorio a subíndices, pero deque no es un espacio continuo real, sino que está empalmado por espacios pequeños continuos. El deque real es similar a Una matriz dinámica bidimensional, su estructura subyacente se muestra en la siguiente figura:

 La capa inferior de la cola de dos extremos es una ilusión de espacio continuo, que en realidad está segmentada y continua. Para mantener su "continuidad general" y la ilusión de acceso aleatorio, cae sobre el iterador de la deque, por lo que El diseño del iterador de la deque es más complicado, como se muestra a continuación:

  3. El defecto del deque

En comparación con el vector, la ventaja de deque es que cuando se inserta y elimina el encabezado, no es necesario mover elementos, lo cual es particularmente eficiente. Y cuando se expande, no necesita mover una gran cantidad de elementos, por lo que su eficiencia es mayor que el vector. En comparación con la lista, su capa inferior es un espacio continuo, la tasa de utilización del espacio es relativamente alta y no es necesario almacenar campos adicionales.
Sin embargo, deque tiene un defecto fatal: no es adecuado para el recorrido, porque al atravesar, el iterador de deque necesita verificar con frecuencia si se ha movido al límite de un espacio pequeño, lo que resulta en una baja eficiencia. Es necesario realizar un recorrido frecuente, por lo que en la práctica, cuando se requiere una estructura lineal, en la mayoría de los casos se da prioridad al vector y a la lista. No hay muchas aplicaciones de deque, y una aplicación que se puede ver hasta ahora es que STL lo usa como la estructura de datos subyacente de pila y cola.

4. ¿Por qué elegir deque como contenedor predeterminado subyacente de pila y cola?

La pila es una estructura de datos lineal especial de último en entrar, primero en salir, por lo que siempre que tenga una estructura lineal con operaciones push_back() y pop_back(), se puede utilizar como contenedor subyacente de la pila, como vector y lista; la cola es una estructura de datos lineal especial primero en entrar, primero en salir, siempre que tenga una estructura lineal con operaciones push_back y pop_front, se puede utilizar como contenedor subyacente de la cola, como la lista. Sin embargo, en STL, deque se selecciona como contenedor subyacente de forma predeterminada para la pila y la cola, principalmente porque:

  1.  No es necesario atravesar la pila y la cola (por lo que la pila y la cola no tienen iteradores) y solo necesitan operar en uno o ambos extremos del fijo.
  2. Cuando los elementos en la pila crecen, deque es más eficiente que el vector (no es necesario mover muchos datos al expandirse); cuando los elementos en la cola crecen, deque no solo es eficiente, sino que también tiene un alto uso de memoria.

Combinando las ventajas del deque, evita perfectamente sus defectos.

Supongo que te gusta

Origin blog.csdn.net/qq_63943454/article/details/132269054
Recomendado
Clasificación