Aula por Lúcio Cardoso
A estrutura de dados Min Queue é uma adaptação da queue do C++. Nela, podemos realizar as seguintes operações:
- Adicionar um elemento de valor atrás da fila
- Remover o elemento da frente da fila
- Responder qual o elemento de menor valor presente na fila
Descrição da Estrutura
Para armazenar as informações da estrutura, utilizaremos um deque. O deque é uma estrutura semelhante à queue, com a diferença de que podemos inserir/remover elementos dos dois lados da fila.
Em particular, cada posição do deque guardará um par de valores: O valor do elemento e o tempo em que foi adicionado (o primeiro elemento adicionado foi adicionado no tempo 1, e assim sucessivamente).
Função
A função insere um elemento de valor na parte de trás da fila.
Seja o elemento atual no fundo da fila. Se , do momento em que foi adicionado em diante, nunca será o valor mínimo na estrutura, pois é menor e, por estar atrás de , será removido em algum tempo depois de . Logo, antes de adicionar , iremos remover todos os elementos do fundo da fila enquanto . Após isso, vamos inserir o par no fundo do deque.
Perceba que, dessa forma, a Min Queue estará sempre ordenada de maneira crescente, e, por tanto, o menor elemento na estrutura será sempre o elemento na frente da fila. Agora, como removemos elementos da estrutura, precisamos de um cuidado adicional na função .
Função
A função remove o elemento presente na frente da fila.
Perceba que, na função , removemos elementos do fundo da fila, e portanto, é possível que o elemento que deveria estar na frente da fila ao executarmos o comando já tenha sido removido.
Para conferir isto, iremos guardar duas variáveis fora da estrutura: e . Estas variáveis indicam, respectivamente, o tempo em que o elemento na frente da fila foi inserido (mesmo se este já foi removido) e o tempo em que será adicionado o próximo elemento no fundo na fila. Assim, é muito simples remover um elemento: Basta checar se o tempo do elemento na frente do deque é igual a . Se sim, removemos ele, senão, o elemento da frente já foi removido antes e não fazemos nada.
Para atualizar as variáveis e , basta somar um no valor de cada vez que adicionarmos um elemento com a função e somar um em a cada vez que removemos um elemento da frente da fila.
Função
A função retorna o elemento de menor valor presente na fila.
Como já dito anteriormente, a estrutura foi mantida de tal forma que o elemento mínimo será aquele na frente da fila. Logo, para retornar o menor elemento, basta retornamos o valor do elemento na frente do deque.
Complexidade
Inicialmente, sabemos que as funções e possuem complexidade . Além disso, cada elemento da estrutura foi removido/adicionado no máximo uma vez. Logo, a complexidade final após todas as operações terem sido realizadas será , onde é o tamanho da fila. Assim, dizemos que cada operação terá complexidade amortizada .
Confira o código final da Min Queue, para melhor entendimento:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Curso Noic de Informática - Estruturas de Dados 11 | |
// Minqueue - Complexidade O(1) amortizada | |
// A Minqueue pode facilmente ser adaptada para Maxqueue, respondendo | |
// o valor máximo na estrutura | |
#include <bits/stdc++.h> | |
using namespace std; | |
typedef pair<int, int> pii; | |
struct MinQueue | |
{ | |
deque<pii> dq; | |
int l, r; | |
// inicialmente, dizemos que l = r = 1 | |
void init(void) | |
{ | |
l = r = 1; | |
dq.clear(); | |
} | |
// adiciona v atrás da fila | |
void push(int v) | |
{ | |
while (!dq.empty() && v < dq.back().ff) dq.pop_back(); | |
dq.push({v, r}); // inserimos v com tempo r | |
r++; // aumentamos o tempo r | |
} | |
// remove o elemento da frente da fila | |
void pop(void) | |
{ | |
if (!dq.empty() && dq.front().ss == l) dq.pop_front(); | |
l++; //aumentamos o tempo l | |
} | |
int getmin(void) {return dq.front().ff;} // retorna o valor mínimo da estrutura | |
}; |