Uno de los primeros artículos de C++ le enseña cola y cola de prioridad (comprensión del uso y la implementación de la simulación)

inserte la descripción de la imagen aquí

que es cola

inserte la descripción de la imagen aquí

  1. Una cola es un adaptador de contenedor diseñado para FIFOoperar en un contexto (primero en entrar, primero en salir) donde los elementos se insertan desde un extremo del contenedor y se extraen desde el otro.
  2. Una cola se implementa como un adaptador de contenedor, que encapsula una clase de contenedor específica como su clase de contenedor subyacente y queueproporciona un conjunto específico de funciones miembro para acceder a sus elementos. Los elementos ingresan a la cola desde la cola y salen de la cola desde la cabeza.
  3. El contenedor subyacente puede ser una de las plantillas de clase de contenedor estándar u otra clase de contenedor especialmente diseñada. El contenedor subyacente soportará al menos las siguientes operaciones:

vacío : comprobar si la cola está vacía
tamaño : devolver el número de elementos válidos en la cola
frente : devolver la referencia del elemento al principio de la cola
atrás : devolver la referencia del elemento al final de la cola
push_back : entrar la cola al final de la cola
pop_front : sale de la cola al principio de la cola

  1. dequeLa suma de las clases de contenedores estándar listcumple con estos requisitos. De forma predeterminada, si no queuese especifica ninguna clase de contenedor para la creación de instancias, se utiliza el contenedor estándar deque.

El uso de la cola

1.constructor de colas

inserte la descripción de la imagen aquí

initialize (1): inicializa la cola con un contenedor existente.

explicit queue(const container_type& ctnr);
Este constructor toma un contenedor existente ctnre inicializa la cola con su contenido.

Ejemplo:

std::deque<int> myDeque = {
    
    1, 2, 3};
std::queue<int> myQueue(myDeque); // 使用已存在的 deque 初始化队列

move-initialize (2): use el contenedor existente para inicializar la cola y vacíe el contenedor original después de la inicialización.

explicit queue(container_type&& ctnr = container_type());
Este constructor toma un contenedor de referencias rvalue ctnr, lo usa para inicializar la cola y lo vacía después de la inicialización ctnr.

Ejemplo:

std::deque<int> myDeque = {
    
    1, 2, 3};
std::queue<int> myQueue(std::move(myDeque)); // 使用已存在的 deque 初始化队列,并清空 myDeque

asignador (3): inicializa la cola con el asignador personalizado Alloc.

template <class Alloc> explicit queue(const Alloc& alloc);
Este constructor acepta un tipo de asignador personalizado Allocque se usa para asignar memoria en la inicialización.

Ejemplo:

std::allocator<int> myAllocator;
std::queue<int> myQueue(myAllocator); // 使用自定义分配器初始化队列

init + asignador (4): inicializa la cola usando un contenedor existente y un asignador personalizado.

template <class Alloc> queue(const container_type& ctnr, const Alloc& alloc);
Este constructor acepta un contenedor existente ctnry un asignador personalizado alloc, que se utiliza para especificar el contenedor y el asignador subyacentes en el momento de la inicialización.

Ejemplo:

std::deque<int> myDeque = {
    
    1, 2, 3};
std::allocator<int> myAllocator;
std::queue<int> myQueue(myDeque, myAllocator); // 使用已存在的 deque 和自定义分配器初始化队列

move-init + asignador (5): inicializa la cola con un contenedor existente y un asignador personalizado, y vacía el contenedor original después de la inicialización.

template <class Alloc> queue(container_type&& ctnr, const Alloc& alloc);
Similar a (2), este constructor acepta un contenedor de referencias de valor real ctnry un asignador personalizado allocque se usa para inicializar la cola y se vacía después de la inicialización ctnr.

Ejemplo:

std::deque<int> myDeque = {
    
    1, 2, 3};
std::allocator<int> myAllocator;
std::queue<int> myQueue(std::move(myDeque), myAllocator); // 使用已存在的 deque 和自定义分配器初始化队列,并清空 myDeque

copiar + asignador (6): copia una cola existente e inicializa una nueva cola con un asignador personalizado.

template <class Alloc> queue(const queue& x, const Alloc& alloc);
Este constructor acepta una cola existente xy un asignador personalizado para copiar elementos a la nueva cola allocen la inicialización .x

Ejemplo:

std::queue<int> originalQueue;
// 添加一些元素到 originalQueue
std::allocator<int> myAllocator;
std::queue<int> myQueue(originalQueue, myAllocator); // 复制已存在队列并使用自定义分配器初始化新队列

mover + asignador (7): mueve una cola existente e inicializa una nueva cola con un asignador personalizado.

template <class Alloc> queue(queue&& x, const Alloc& alloc);
De forma similar a (5), este constructor acepta una cola de referencias de valor real xy un asignador personalizado allocpara inicializar una nueva cola y xmover elementos de ella.

Ejemplo:

std::queue<int> originalQueue;
// 添加一些元素到 originalQueue
std::allocator<int> myAllocator;
std::queue<int> myQueue(std::move(originalQueue), myAllocator); // 移动已存在队列并使用自定义分配器初始化新队列

2.vacío()

bool empty() constEs std::queueuna de las funciones miembro de la clase, utilizada para determinar si la cola está vacía. Esta función no modifica el contenido de la cola, por lo que se declara como const, indicando que no modificará el objeto.

valor de retorno:

Devuelve si la cola está vacía true.
Devuelve si la cola no está vacía false.

Ejemplo de uso:

#include <iostream>
#include <queue>

int main() {
    
    
    std::queue<int> myQueue;
    
    if (myQueue.empty()) {
    
    
        std::cout << "Queue is empty." << std::endl;
    } else {
    
    
        std::cout << "Queue is not empty." << std::endl;
    }
    
    myQueue.push(42);
    
    if (myQueue.empty()) {
    
    
        std::cout << "Queue is empty." << std::endl;
    } else {
    
    
        std::cout << "Queue is not empty." << std::endl;
    }
    
    return 0;
}

En este ejemplo, primero se crea una cola vacía myQueuey luego empty()se usa la función para determinar si la cola está vacía. Después de agregar un elemento, empty()vuelva a llamar a la función para verificar el estado de la cola. A partir de la salida, puede ver que la cola está vacía cuando no tiene elementos y no está vacía después de agregar un elemento.

3.tamaño()

size_type size() constEs std::queueuna de las funciones miembro de la clase, utilizada para obtener el número de elementos en la cola. Esta función no modifica el contenido de la cola, por lo que se declara como const, indicando que no modificará el objeto.

valor de retorno:

Devuelve el número actual de elementos (tamaño) en la cola.

Ejemplo de uso:

#include <iostream>
#include <queue>

int main() {
    
    
    std::queue<int> myQueue;
    
    std::cout << "Initial size: " << myQueue.size() << std::endl;
    
    myQueue.push(42);
    myQueue.push(20);
    myQueue.push(10);
    
    std::cout << "Updated size: " << myQueue.size() << std::endl;
    
    return 0;
}

En este ejemplo, primero cree una cola vacía myQueue, luego use size()la función para obtener el tamaño inicial de la cola. Luego agregue tres elementos a la cola y size()vuelva a llamar a la función para obtener el tamaño de cola actualizado. En el resultado, puede ver que la cola cambió de tamaño después de agregar elementos.

4.frente()

reference& front()y const_reference& front() constes std::queueuna de las funciones miembro de la clase utilizada para acceder al elemento frontal (cabeza) de la cola. Estas funciones no modifican el contenido de la cola, por lo que se declaran como consto devuelven referencias constantes, indicando que no modifican el objeto.

referencey const_referenceson Tel tipo de referencia y el tipo de referencia constante del parámetro de plantilla, que se utilizan para representar el tipo y el tipo de referencia constante de los elementos de la cola, respectivamente. La referencia devuelta le permite acceder al primer elemento de la cola.

Ejemplo de uso:

#include <iostream>
#include <queue>

int main() {
    
    
    std::queue<int> myQueue;
    
    myQueue.push(42);
    myQueue.push(20);
    
    int& firstElement = myQueue.front();
    const int& constFirstElement = myQueue.front();
    
    std::cout << "First element: " << firstElement << std::endl;
    std::cout << "Constant first element: " << constFirstElement << std::endl;
    
    return 0;
}

En este ejemplo, primero se crea una cola myQueuey luego se agregan dos elementos. front()Obtenga el primer elemento de la cola a través de la función y guárdelo en una referencia no constante firstElementy una referencia constante constFirstElement. En el resultado, puede ver que ambas referencias pueden acceder al valor del primer elemento de la cola.

5.atrás();

reference& back()y const_reference& back() constes std::queueuna de las funciones miembro de la clase utilizada para acceder al último elemento (cola) de la cola. Estas funciones no modifican el contenido de la cola, por lo que se declaran como consto devuelven referencias constantes, indicando que no modifican el objeto.

referencey const_referenceson Tel tipo de referencia y el tipo de referencia constante del parámetro de plantilla, que se utilizan para representar el tipo y el tipo de referencia constante de los elementos de la cola, respectivamente. La referencia devuelta le permite acceder al último elemento de la cola.

Ejemplo de uso:

#include <iostream>
#include <queue>

int main() {
    
    
    std::queue<int> myQueue;
    
    myQueue.push(42);
    myQueue.push(20);
    
    int& lastElement = myQueue.back();
    const int& constLastElement = myQueue.back();
    
    std::cout << "Last element: " << lastElement << std::endl;
    std::cout << "Constant last element: " << constLastElement << std::endl;
    
    return 0;
}

En este ejemplo, primero se crea una cola myQueuey luego se agregan dos elementos. Obtenga el último elemento de la cola a través de back()la función y guárdelo en una referencia no constante lastElementy una referencia constante constLastElement. En el resultado, puede ver que ambas referencias pueden acceder al valor del último elemento de la cola.

6. empujar

void push (const value_type& val)y void push (value_type&& val)es una de las funciones miembro de la clase std::queue y se usa para agregar elementos al final de la cola.

const value_type& valEs una referencia constante utilizada para pasar el elemento que debe agregarse a la cola.
value_type&& vales una referencia de valor real que se usa para pasar el elemento que debe agregarse a la cola, generalmente se usa para admitir la semántica de movimiento.

Ejemplo de uso:

#include <iostream>
#include <queue>

int main() {
    
    
    std::queue<int> myQueue;
    
    myQueue.push(42); // 使用右值
    int value = 20;
    myQueue.push(value); // 使用左值
    
    return 0;
}

En este ejemplo, primero se crea una cola myQueuey luego push()se agregan dos valores de diferentes tipos a la cola usando la función. El primero push()usa rvalues 42, el segundo push()usa lvalue variables value. La cola mantendrá los elementos en el orden en que se agregaron.

7.lugar

template <class... Args> void emplace (Args&&... args)Es std::queueuna de las funciones miembro de la clase utilizada para construir un nuevo elemento directamente al final de la cola a través de la lista de parámetros del constructor.

Args... argses un paquete de parámetros de plantilla que representa la lista de parámetros pasados ​​al constructor.
Utilice emplace()la función para evitar operaciones adicionales de copia o movimiento de objetos y construya directamente el objeto dentro del contenedor.

Ejemplo de uso:

#include <iostream>
#include <queue>

class MyObject {
    
    
public:
    MyObject(int value) : m_value(value) {
    
    
        std::cout << "Constructed: " << m_value << std::endl;
    }
    
    ~MyObject() {
    
    
        std::cout << "Destructed: " << m_value << std::endl;
    }

private:
    int m_value;
};

int main() {
    
    
    std::queue<MyObject> myQueue;
    
    myQueue.emplace(42); // 使用右值参数构造
    myQueue.emplace(20); // 使用右值参数构造
    
    return 0;
}

En este ejemplo, primero se crea una cola myQueuey luego emplace()se usa la función para construir dos objetos directamente al final de la cola a través de los parámetros rvalue MyObject. Debido al uso de emplace(), el objeto se construirá directamente en la cola sin que se produzcan operaciones adicionales de copia o movimiento.

8.pop()

void pop()Es std::queueuna de las funciones miembro de la clase, que se utiliza para eliminar de la cola el elemento que se encuentra al principio de la cola.

Llamar pop()a la función elimina el primer elemento de la cola y mueve los elementos restantes de la cola hacia adelante para ocupar el lugar del elemento eliminado.

Ejemplo de uso:

#include <iostream>
#include <queue>

int main() {
    
    
    std::queue<int> myQueue;
    
    myQueue.push(42);
    myQueue.push(20);
    myQueue.push(10);
    
    std::cout << "Size before pop: " << myQueue.size() << std::endl;
    
    myQueue.pop();
    
    std::cout << "Size after pop: " << myQueue.size() << std::endl;
    
    return 0;
}

En este ejemplo, primero cree una cola myQueuey luego use push()la función para agregar tres elementos a la cola. Al llamar pop()a la función, se elimina el elemento al principio de la cola 42. En el resultado, puede ver que pop()el tamaño de la cola se reduce después de llamar a .

9.intercambiar

void swap(queue& x) noexceptEs std::queueuna de las funciones miembro de la clase, utilizada para intercambiar xel contenido de la cola actual y otra cola.

x: Otra cola para intercambiar con la cola actual.
noexcept: Esta función se declara como que no lanza una excepción, lo que significa que no se lanzará ninguna excepción durante el intercambio.

Ejemplo de uso:

#include <iostream>
#include <queue>

int main() {
    
    
    std::queue<int> queue1;
    std::queue<int> queue2;

    queue1.push(42);
    queue1.push(20);
    
    queue2.push(10);

    std::cout << "Before swap:" << std::endl;
    std::cout << "Queue 1 front: " << queue1.front() << std::endl;
    std::cout << "Queue 2 front: " << queue2.front() << std::endl;

    queue1.swap(queue2);

    std::cout << "After swap:" << std::endl;
    std::cout << "Queue 1 front: " << queue1.front() << std::endl;
    std::cout << "Queue 2 front: " << queue2.front() << std::endl;

    return 0;
}

En este ejemplo, primero cree dos colas queue1y queue2agrégueles elementos respectivamente. Al llamar swap()a la función, se intercambian los contenidos de la cola. A partir de la salida, puede ver que después del intercambio, también se intercambiaron los contenidos de la cola.

Implementación de simulación de colas

#pragma once
#include <deque>

namespace xzq
{
    
    
	template<class T, class Container = deque<T>>
	class queue
	{
    
    
	public:
		void push(const T& x)
		{
    
    
			_con.push_back(x);
		}

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

		T& back()
		{
    
    
			return _con.back();
		}

		T& front()
		{
    
    
			return _con.front();
		}

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

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


		bool empty()  const
		{
    
    
			return _con.empty();
		}

		size_t size() const
		{
    
    
			return _con.size();
		}
	private:
		Container _con;
	};
}

Primero, esta clase de cola toma un Containerparámetro de plantilla llamado con un valor predeterminado de std::deque<T>. Esto le permite especificar el tipo de contenedor subyacente al crear el objeto de cola; si no se especifica, se utilizará el valor predeterminado std::deque.

push(const T& x)se usa para xagregar un elemento al final de la cola, en realidad llama push_back()al método del contenedor subyacente.

pop()se usa para eliminar el elemento al principio de la cola, en realidad llama pop_front()al método del contenedor subyacente.

back()La función devuelve una referencia al último elemento de la cola, que se puede utilizar para acceder al elemento final de la cola.

front()La función devuelve una referencia al primer elemento de la cola, que se utiliza para acceder al elemento principal de la cola.

empty()función para verificar si la cola está vacía, en realidad llama empty()al método del contenedor subyacente.

size()se utiliza para obtener el número de elementos en la cola, en realidad llama size()al método del contenedor subyacente.

El miembro privado _cones el objeto contenedor subyacente que se utiliza para almacenar los elementos de la cola.

Con esta clase de cola simulada, puede elegir diferentes tipos de contenedores subyacentes (el valor predeterminado es std::deque) y llamar a los métodos de la clase para simular las operaciones básicas de la cola, como agregar elementos, eliminar elementos, acceder a elementos, juzgar si son vacío, etc Esta implementación le permite usar las colas de manera más flexible a través de plantillas para adaptarse a diferentes tipos de datos y contenedores subyacentes.

¿Qué es la prioridad_cola?

inserte la descripción de la imagen aquí

  1. Una cola de prioridad es un adaptador de contenedor cuyo primer elemento es siempre el más grande de los elementos contenidos de acuerdo con estrictos criterios de ordenamiento débil.
  2. Este contexto es similar a un montón, donde los elementos se pueden insertar en cualquier momento y solo se puede recuperar el elemento de montón más grande (el que está en la parte superior de la cola de prioridad).
  3. La cola de prioridad se implementa como un adaptador de contenedor, que encapsula una clase de contenedor específica como su clase de contenedor subyacente y queueproporciona un conjunto de funciones miembro específicas para acceder a sus elementos. Los elementos se extraen de la "cola" de un contenedor en particular, que se denomina la parte superior de la cola de prioridad.
  4. El contenedor subyacente puede ser cualquier plantilla de clase de contenedor estándar o cualquier otra clase de contenedor de un diseño específico. Los contenedores deben ser accesibles a través de iteradores de acceso aleatorio y admitir las siguientes operaciones:

empty() : comprueba si el contenedor está vacío
size() : devuelve el número de elementos válidos en el contenedor
front() : devuelve la referencia al primer elemento del contenedor
push_back() : inserta un elemento al final del contenedor
pop_back() : Elimina el elemento al final del contenedor

  1. Clases de contenedores estándar vectory dequesatisfacer estas necesidades. De forma predeterminada, si no priority_queuese especifica ninguna clase de contenedor para una instancia de clase en particular, se utiliza vector.
  2. Los iteradores de acceso aleatorio deben admitirse para que la estructura del montón siempre se mantenga internamente. El adaptador de contenedor hace esto automáticamente llamando automáticamente a funciones algorítmicas make_heapy cuando push_heapes necesario .pop_heap

El uso de la prioridad_cola

1. constructor de cola de prioridad

inserte la descripción de la imagen aquí
std::priority_queuees C++ STLun contenedor de cola de prioridad proporcionado por , que se implementa en función de un montón, lo que le permite agregar y eliminar elementos en un orden específico.

Las siguientes son explicaciones y ejemplos de estos constructores:

priority_queue(const Compare& comp, const Container& ctnr): Construye una cola de prioridad, utilizando la función de comparación dada compy el contenedor subyacente ctnr.

priority_queue(InputIterator first, InputIterator last, const Compare& comp, const Container& ctnr): Construye una cola de prioridad usando los elementos en el rango del iterador [first, last)con la función de comparación dada compy el contenedor subyacente ctnr.

explicit priority_queue(const Compare& comp = Compare(), Container&& ctnr = Container()): Construye una cola de prioridad, usando la función de comparación dada compy el contenedor subyacente pasado con semántica de movimiento ctnr.

template <class InputIterator> priority_queue(InputIterator first, InputIterator last, const Compare& comp, Container&& ctnr = Container()): Construye una cola de prioridad usando los elementos en el rango del iterador y el contenedor subyacente pasado [first, last)con la función de comparación dada y la semántica de movimiento .compctnr

AllocatorVersión: estos constructores usan un asignador diferente allocatorpara construir la cola de prioridad.

Ejemplo:

#include <iostream>
#include <queue>
#include <vector>

int main() {
    
    
    // 使用默认底层容器 std::vector,以默认比较函数(最大堆)构造优先队列
    std::priority_queue<int> maxHeap;

    // 使用自定义比较函数(最小堆)和底层容器 std::deque 构造优先队列
    auto compare = [](int a, int b) {
    
     return a > b; };
    std::deque<int> container = {
    
    5, 3, 8, 1, 9};
    std::priority_queue<int, std::deque<int>, decltype(compare)> minHeap(compare, container);

    // 使用迭代器范围构造优先队列
    std::vector<int> elements = {
    
    7, 2, 4, 6, 0};
    std::priority_queue<int, std::vector<int>> iteratorQueue(elements.begin(), elements.end());

    // 输出优先队列中的元素
    while (!iteratorQueue.empty()) {
    
    
        std::cout << iteratorQueue.top() << " ";
        iteratorQueue.pop();
    }

    return 0;
}

En este ejemplo, demostramos el uso de diferentes constructores. En primer lugar, se construye una cola de prioridad de pila máxima utilizando el constructor predeterminado. std::dequeLuego, construimos una cola de prioridad de montón mínimo usando una función de comparación personalizada y el contenedor subyacente . Finalmente, se construye una cola de prioridad usando el rango del iterador. Según la salida, puede ver que la cola de prioridad genera elementos en un orden diferente.

1.1 Parámetro de plantilla Comparar

En std::priority_queuela clase, Compareel objeto de función utilizado para comparar elementos se especifica a través del parámetro de plantilla para afectar el método de clasificación del montón. CompareEs unfuntor, que define cómo se comparan los elementos. Según la Compareprioridad, la cola puede convertirse en un montón grande (montón máximo) o en un montón pequeño (montón mínimo).

Predeterminado std::less<T>(montón grande):
std::less es un objeto de función que sobrecarga operator() para comparar dos elementos. Devuelve un booleano que indica si el primer argumento es menor que el segundo argumento. De forma predeterminada, si no se proporciona el parámetro Comparar, la cola de prioridad usa std::less como el objeto de la función de comparación, es decir, un montón grande. Esto significa que en un montón grande, el valor del nodo principal siempre es mayor o igual que el valor del nodo secundario.

std::greater<T>(Pequeño montón):
std::greater<T> es otro objeto de función, que está sobrecargado operator()y se usa para comparar dos elementos. A diferencia de std::less<T>, std::greater<T>devuelve un booleano que indica si el primer argumento es mayor que el segundo argumento. Si std::greater<T>pasa a priority_queue, construirá un pequeño montón. En un montón pequeño, el valor del nodo principal siempre es menor o igual que el valor del nodo secundario.

El siguiente es un código de muestra que demuestra cómo usar diferentes objetos de función de comparación para crear montones grandes y pequeños:

#include <iostream>
#include <queue>

int main() {
    
    
    std::priority_queue<int> maxHeap; // 默认大堆

    std::priority_queue<int, std::vector<int>, std::greater<int>> minHeap; // 小堆

    maxHeap.push(5);
    maxHeap.push(3);
    maxHeap.push(8);

    minHeap.push(5);
    minHeap.push(3);
    minHeap.push(8);

    std::cout << "Max Heap (Top element): " << maxHeap.top() << std::endl;
    std::cout << "Min Heap (Top element): " << minHeap.top() << std::endl;

    return 0;
}

En este ejemplo, creamos un montón grande y un montón pequeño por separado. A través top()de la función, podemos ver que el elemento superior de la pila grande es el más grande y el elemento superior de la pila pequeña es el más pequeño. Esto refleja el efecto de diferentes objetos de función de comparación.

1.2 ¿Qué es un funtor?

Un functor es un objeto de clase que sobrecarga el operador de llamada de función operator()para que el objeto pueda llamarse como una función. En realidad, es un objeto de función, que puede tener sus propias variables miembro y operaciones, y puede usarse de manera similar a las funciones ordinarias.

Una de las principales ventajas de usar funtores es que puede encapsular el comportamiento y el estado de una función en un objeto, lo que hace que su código sea más legible y fácil de mantener. Los funtores se pueden usar en una variedad de situaciones, incluidos algoritmos estándar, STLcontenedores y otros lugares donde se requieren operaciones funcionales.

Una clase de funtor generalmente requiere al menos la implementación operator(), que puede tener diferentes parámetros y tipos de devolución, según el propósito del funtor. Aquí hay un ejemplo simple:

#include <iostream>

class Adder {
    
    
public:
    Adder(int value) : value_(value) {
    
    }

    int operator()(int x) {
    
    
        return x + value_;
    }

private:
    int value_;
};

int main() {
    
    
    Adder addFive(5);
    Adder addTen(10);

    int result1 = addFive(7); // 调用仿函数 addFive
    int result2 = addTen(7);  // 调用仿函数 addTen

    std::cout << "Result 1: " << result1 << std::endl;
    std::cout << "Result 2: " << result2 << std::endl;

    return 0;
}

En este ejemplo, Adderla clase se define como un funtor que toma un valor entero y agrega ese valor al argumento pasado cuando se le llama. En main()la función, creamos dos Adderobjetos addFivey addTenluego realizamos la operación de suma llamándolos.

En resumen, un funtor es un objeto de función que permite que un objeto se llame como una función, de modo que el comportamiento y el estado de la función se puedan encapsular en un objeto. Esto es muy útil cuando se escribe código más flexible y legible.

2.vacío()

bool empty() constEs std::priority_queueuna de las funciones miembro de la clase, utilizada para verificar si la cola de prioridad está vacía.

empty()La función devuelve un valor booleano que indica si la cola de prioridad está vacía.
constEl modificador indica que esta función no modificará el contenido de la cola de prioridad.

Ejemplo de uso:

#include <iostream>
#include <queue>

int main() {
    
    
    std::priority_queue<int> maxHeap;

    if (maxHeap.empty()) {
    
    
        std::cout << "The priority queue is empty." << std::endl;
    } else {
    
    
        std::cout << "The priority queue is not empty." << std::endl;
    }

    maxHeap.push(42);

    if (maxHeap.empty()) {
    
    
        std::cout << "The priority queue is empty." << std::endl;
    } else {
    
    
        std::cout << "The priority queue is not empty." << std::endl;
    }

    return 0;
}

En este ejemplo, primero creamos un std::priority_queueobjeto vacío maxHeap, luego usamos empty()la función para verificar si está vacío. En el resultado, puede ver que la cola de prioridad ya no está vacía después de agregar un elemento.

3.tamaño()

size_type size() constEs std::priority_queueuna de las funciones miembro de la clase, utilizada para obtener el número de elementos en la cola de prioridad.

size()La función devuelve un entero sin signo size_typeque representa el número de elementos en la cola de prioridad.
constEl modificador indica que esta función no modificará el contenido de la cola de prioridad.

Ejemplo de uso:

#include <iostream>
#include <queue>

int main() {
    
    
    std::priority_queue<int> maxHeap;

    maxHeap.push(42);
    maxHeap.push(20);
    maxHeap.push(10);

    std::cout << "Size of the priority queue: " << maxHeap.size() << std::endl;

    return 0;
}

En este ejemplo, creamos una gran cola de prioridad de montón con tres elementos maxHeapy luego usamos size()la función para obtener la cantidad de elementos en la cola. En la salida, puede ver que hay tres elementos en la cola.

4.superior()

const_reference top() constEs std::priority_queueuna de las funciones miembro de la clase, que se usa para obtener el elemento superior de la cola de prioridad (el elemento más grande o el elemento más pequeño, según el tipo de montón), pero no cambia el contenido de la cola.

top()La función devuelve una referencia constante al elemento superior de la cola const_reference, ya sea el elemento más grande o el elemento más pequeño.
constEl modificador indica que esta función no modificará el contenido de la cola de prioridad.

Ejemplo de uso:

#include <iostream>
#include <queue>

int main() {
    
    
    std::priority_queue<int> maxHeap;

    maxHeap.push(42);
    maxHeap.push(20);
    maxHeap.push(10);

    std::cout << "Top element: " << maxHeap.top() << std::endl;

    return 0;
}

En este ejemplo, creamos una cola de prioridad de montón grande maxHeapy agregamos tres elementos. Usando top()la función, obtenemos el elemento superior (elemento más grande) en la cola. Según el resultado, puede ver que el valor del elemento superior es 42.

5. empujar

void push(const value_type& val)y void push(value_type&& val)es std::priority_queueuna de las funciones miembro de la clase utilizada para agregar nuevos elementos a la cola de prioridad.

push(const value_type& val) Toma una referencia constante valy copia un nuevo elemento en la cola de prioridad.
push(value_type&& val)Toma una referencia de valor r val, usando la semántica de movimiento para mover un nuevo elemento a la cola de prioridad.

Ejemplo de uso:

#include <iostream>
#include <queue>

int main() {
    
    
    std::priority_queue<int> maxHeap;

    maxHeap.push(42); // 使用 push(const value_type& val)
    maxHeap.push(20); // 使用 push(const value_type& val)
    maxHeap.push(10); // 使用 push(const value_type& val)

    std::cout << "Top element: " << maxHeap.top() << std::endl;

    return 0;
}

En este ejemplo, agregamos elementos a la cola de prioridad masiva usando dos métodos diferentes maxHeap. El primero es usar push(const value_type& val), el segundo es usar push(value_type&& val). Ambas formas agregan elementos a la cola. De acuerdo con el resultado, puede ver que el valor del elemento superior se 42debe a que la cola de prioridad coloca automáticamente el elemento más grande (o más pequeño) en la parte superior.

6.lugar

template <class... Args> void emplace(Args&&... args)Es std::priority_queueuna de las funciones miembro de la clase, utilizada para insertar un nuevo elemento en la cola de prioridad por medio de una construcción in situ.

emplace()Las funciones usan paquetes de parámetros parameter packpara aceptar los parámetros necesarios para construir elementos.
Se puede insertar en elementos existentes, evitando operaciones adicionales de copiar o mover, mejorando la eficiencia.
Esta función usa el reenvío perfecto para pasar argumentos para acomodar diferentes tipos de constructores.

Ejemplo de uso:

#include <iostream>
#include <queue>

int main() {
    
    
    std::priority_queue<int> maxHeap;

    maxHeap.emplace(42); // 插入一个新元素

    int value = 20;
    maxHeap.emplace(value); // 插入一个新元素,使用拷贝构造函数

    maxHeap.emplace(10); // 插入一个新元素

    std::cout << "Top element: " << maxHeap.top() << std::endl;

    return 0;
}

En este ejemplo, usamos emplace()la función para insertar nuevos elementos en la cola de prioridad masiva con construcción en el lugar maxHeap. Al insertar, podemos pasar los parámetros necesarios para construir el elemento. Esta función llama automáticamente al constructor apropiado para insertar nuevos elementos en el montón. Según el resultado, puede ver que el valor del elemento superior es 42.

7.pop()

void pop()Es std::priority_queueuna de las funciones miembro de la clase que elimina el elemento superior de la cola de prioridad (ya sea el elemento más grande o el elemento más pequeño, según el tipo de montón).

pop()La función elimina el elemento superior de la cola de prioridad, mientras reajusta el montón para mantener las propiedades del montón.
Tenga en cuenta que debe asegurarse de que la cola no esté vacía antes de llamar a esta función; de lo contrario, se producirá un comportamiento indefinido.

Ejemplo de uso:

#include <iostream>
#include <queue>

int main() {
    
    
    std::priority_queue<int> maxHeap;

    maxHeap.push(42);
    maxHeap.push(20);
    maxHeap.push(10);

    std::cout << "Top element before pop: " << maxHeap.top() << std::endl;

    maxHeap.pop();

    std::cout << "Top element after pop: " << maxHeap.top() << std::endl;

    return 0;
}

En este ejemplo, primero creamos una cola de prioridad de montón grande maxHeapy luego push()agregamos tres elementos usando la función. Con top()la función, obtenemos el elemento superior de la cola. Luego, usamos pop()la función para eliminar el elemento superior y top()obtener el nuevo elemento superior a través de la función nuevamente. A partir de la salida, puede ver que después de eliminar un elemento, el elemento superior de la cola se convierte en 20.

8.intercambiar

void swap(priority_queue& x) noexceptEs std::priority_queueuna de las funciones miembro de la clase, utilizada para intercambiar el contenido de dos colas de prioridad.

swap()La función se utiliza para intercambiar el contenido entre el objeto que llama y el parámetro x pasado.
Esta operación hace que se intercambien los contenidos de las dos colas de prioridad, pero no cambia sus funciones de comparación ni otras propiedades.
noexceptLa palabra clave indica que esta función no generará excepciones.

Ejemplo de uso:

#include <iostream>
#include <queue>

int main() {
    
    
    std::priority_queue<int> maxHeap1;
    std::priority_queue<int> maxHeap2;

    maxHeap1.push(42);
    maxHeap1.push(20);

    maxHeap2.push(10);
    maxHeap2.push(30);

    std::cout << "Max Heap 1 (Top element before swap): " << maxHeap1.top() << std::endl;
    std::cout << "Max Heap 2 (Top element before swap): " << maxHeap2.top() << std::endl;

    maxHeap1.swap(maxHeap2);

    std::cout << "Max Heap 1 (Top element after swap): " << maxHeap1.top() << std::endl;
    std::cout << "Max Heap 2 (Top element after swap): " << maxHeap2.top() << std::endl;

    return 0;
}

En este ejemplo, creamos dos montones grandes, cola de prioridad maxHeap1y maxHeap2, y agregamos diferentes elementos a cada uno. Con top()la función, obtenemos los elementos superiores de las dos colas. Luego, usando swap()la función, intercambiamos el contenido de las dos colas. A partir de la salida, puede ver que después del intercambio, se intercambian los contenidos de las dos colas.

Simular la implementación de priority_queue

#pragma once

namespace xzq
{
    
    
	// Compare进行比较的仿函数 less->大堆
	// Compare进行比较的仿函数 greater->小堆
	template<class T, class Container = vector<T>, class Compare = std::less<T>>
	class priority_queue
	{
    
    
	public:
		priority_queue()
		{
    
    }

		template <class InputIterator>         
		priority_queue(InputIterator first, InputIterator last)
		{
    
    
			while (first != last)
			{
    
    
				_con.push_back(*first);
				++first;
			}

			for (int i = (_con.size()-1-1)/2; i >= 0; --i)
			{
    
    
				adjust_down(i);
			}
		}

		void adjust_up(size_t child)
		{
    
    
			Compare com;
			size_t parent = (child - 1) / 2;
			while (child > 0)
			{
    
    
				if (com(_con[parent], _con[child]))
				{
    
    
					std::swap(_con[child], _con[parent]);
					child = parent;
					parent = (child - 1) / 2;
				}
				else
				{
    
    
					break;
				}
			}
		}

		void push(const T& x)
		{
    
    
			_con.push_back(x);
			adjust_up(_con.size() - 1);
		}

		void adjust_down(size_t parent)
		{
    
    
			Compare com;
			size_t child = parent * 2 + 1;
			while (child < _con.size())
			{
    
    
				if (child + 1 < _con.size() && com(_con[child],_con[child + 1]))
				{
    
    
					++child;
				}


				if (com(_con[parent],_con[child]))
				{
    
    
					std::swap(_con[child], _con[parent]);
					parent = child;
					child = parent * 2 + 1;
				}
				else
				{
    
    
					break;
				}
			}
		}

		void pop()
		{
    
    
			std::swap(_con[0], _con[_con.size() - 1]);
			_con.pop_back();

			adjust_down(0);
		}

		const T& top()
		{
    
    
			return _con[0];
		}

		bool empty()  const
		{
    
    
			return _con.empty();
		}

		size_t size() const
		{
    
    
			return _con.size();
		}

	private:
		Container _con;
	};
}

Espacio de nombres xzq:
este código se encuentra en el espacio de nombres xzq, que es un espacio de nombres personalizado que se usa para encapsular clases relacionadas, funciones, etc. para evitar conflictos de nombres con otros códigos.

Clase de plantilla cola_prioridad:
esta es una clase de plantilla que representa la implementación de una cola de prioridad. Toma tres argumentos de plantilla: T(tipo de elemento), Container(tipo de contenedor subyacente, por defecto es std::vector<T>) y Compare(funtor para comparar elementos, por defecto es std::less<T>)

Comparees un parámetro de plantilla utilizado para comparar elementos. Es un funtor que puede ser std::less<T>(predeterminado) o std::greater<T>, según el tipo de cola de prioridad proporcionado por el usuario. CompareEl functor se usa para determinar el orden de los elementos en el montón, determinando así si es un montón máximo o un montón mínimo. En priority_queuecada función miembro de la clase, Comparela comparación de elementos se realiza llamando al funtor, realizando así la operación de insertar y ajustar el montón.

Constructor priority_queue():
este es un constructor predeterminado que no necesita usar Comparefuntores para la comparación.

Priority_queue de plantilla de constructor (InputIterator primero, InputIterator último):
dentro del constructor, use Compareel functor para realizar operaciones de comparación para determinar el orden de los elementos. Después de agregar elementos, adjust_downel montón se construye llamando a la función.

Función miembro adjust_up(size_t child):
en la operación float, use Compareel functor para realizar una comparación para determinar si se intercambian las posiciones de los nodos principal y secundario, manteniendo así la naturaleza del montón.

Función miembro push(const T& x):
en la operación de inserción, primero agregue el nuevo elemento al contenedor subyacente _cony luego adjust_uprealice la operación flotante llamando a la función para asegurarse de que el nuevo elemento esté en una posición adecuada.

Función miembro adjust_down(size_t parent):
en la operación de sumidero, Compareel functor se usa para realizar una comparación para determinar si la posición de los nodos principal y secundario debe intercambiarse, manteniendo así la naturaleza del montón.

Función miembro pop ():
en la operación de eliminación, primero intercambie el elemento superior con el último elemento del contenedor inferior y luego realice la operación de hundimiento llamando a la función adjust_down para garantizar la naturaleza del montón.

Función miembro const T& top(): Obtenga el elemento superior de la cola de prioridad
devolviendo ._con[0]

epílogo

Los amigos interesados ​​​​pueden prestar atención al autor, si cree que el contenido es bueno, haga un enlace triple con un clic, ¡cangrejo cangrejo! ! !
No es fácil de hacer, por favor señale si hay alguna inexactitud
Gracias por su visita, ver UU es la motivación para perseverar.
Con el catalizador del tiempo, ¡seamos mejores personas los unos de los otros! ! !

Supongo que te gusta

Origin blog.csdn.net/kingxzq/article/details/132256833
Recomendado
Clasificación