Fila de Prioridade e Heap
Uma fila de prioridade é uma estrutura de dados com duas operações básicas:
- Inserir um novo elemento
- Remover o elemento com maior chave (prioridade)
Pilhas e filas assemelham-se às filas de prioridade, na primeira o elemento de maior prioridade é o último inserido, e nas filas o contrário acontece.
Implementação
A troca de elementos será frequente, então para facilitar a leitura do código, foi implementada a função troca.
Criação da fila prioridade
A criação da fila de prioridade consiste basicamente em alocar memória para as estruturas e definir o tamanho com e quantidade de valores preenchidos.
| criar.c | |
|---|---|
Inserção
A inserção é simples e feita no final do vetor.
A complexidade do algoritmo é \(O(1)\).
Remoção do máximo
O algoritmo percorre o vetor, guardando o índice do maior valor encontrado até o momento. No final, é feita a troca do último elemento do vetor fprio->v[fprio->n-1] com o maior valor encontrado fprio->v[max]. Então, o valor de n é decrementado, pois um item foi removido, e o valor removido é retornado.
| extrair_maximo.c | |
|---|---|
A complexidade da extração do máximo é \(O(n)\).
Os custos das operações inserção e extração são invertidas caso se deseje manter o vetor ordenado.
Cheia vs Vazia
Para verificar se a fila está cheia, ou vazia, podemos usar as funções a seguir.
Heap
Definição
O heap de máximo é uma árvore em que os filhos de cada nó são menores ou iguais ao pai. Simetricamente, no heap de mínimo os filhos são maiores ou iguais ao pai. Essa estrutura possui a propriedade de alocar o maior (ou menor) elemento na raiz da árvore.
Um heap não é uma árvore binária de busca, nele os dados estão bem menos estruturados, pois o interesse está apenas em encontrar o maior (ou menor) valor.
Figura 1: Heap de Máximo. Fonte: [1]
Implementação
O Heap pode ser representado na forma de arvore binária completa, utilizando vetores.
Subindo e Descendo no Heap
| sobenoheap.c | |
|---|---|
Inserção
| heap.c | |
|---|---|
A inserção custa \(O(log\ n)\), pois subimos no máximo até a raiz.
Extraindo o máximo
| getmaximoheap.c | |
|---|---|
Extrair o valor máximo custa \(O(log\ n)\), pois descemos no máximo a altura da árvore.
Mudando a prioridade
Se a prioridade do item aumentar, precisamos subir arrumando, caso contrário, descer arrumando.
| alteraprioridade.c | |
|---|---|
Para alterar a prioridade precisamos saber a posição do item no heap, e a busca por essa posição tem custo \(O(n)\). Podemos melhorar esse custo incluindo um campo id com valores de 0 a n-1 nos itens, criando um vetor de n posições como parte do heap armazenando a posição de cada item no heap, então podemos recuperar essa posição em \(O(1)\).
Referências
[1] Fila de Prioridade e Heap - Notas de aula do professor Rafael C. S. Schouery, disponíveis no link.