Uma generalização interessante da lista de prioridades permite o acesso, em tempo
constante, não só ao maior elemento da tabela como também ao menor. Essa estrutura será aqui chamada lista de prioridades min-max. Nesse caso, como na lista de prioridades apresentada nas seções anteriores, a implementação se faz através de uma lista linear com características especiais, denominada heap min-max. Seja S uma lista linear em que cada nó i corresponde à chave si, 1 ≤i ≤n. Define-se nivel(i) = ⎣log i⎦ + 1. O nó i está situado num nível denominado máximo se seu nível é par, e num nível denominado mínimo em caso contrário. S constitui um heap min-max se s1 é a menor chave e, para todo i > 1, i está situado num nível mínimo:
i está situado num nível máximo:
Novamente a visualização das propriedades se faz mais óbvia utilizando-se a árvore
binária completa. O nível do elemento na lista corresponde a seu nível na árvore; então, o nível da raiz é mínimo, o de seus filhos máximo, e assim alternadamente. As propriedades (ii) e (iii) ((iv) e (v)), aplicadas recursivamente, mostram que a prioridade do nó i, situado num nível ímpar (par), é menor (maior) que a prioridade de seus descendentes (Exercício 6.13). A Figura 6.7 ilustra um exemplo de tabela assim construída. A Figura 6.8 mostra as relações de ordem que estão implícitas na árvore do exemplo. Como indicam as setas entre os nós, a relação < pode ser lida de cima para baixo; a relação >, de baixo para cima. Infelizmente, a correspondência entre o aumento e a diminuição de prioridades e o percurso na árvore para cima ou para baixo não mais se verifica para todos os elementos, em virtude da alternância de relações de nível para nível. Em consequência, o problema de alteração de prioridades será restrito aos nós situados no primeiro nível mínimo, no primeiro nível máximo e no último nível da árvore. Estes são exatamente os que nos interessam para realizar as operações de retirar o mínimo, retirar o máximo e inserir um novo elemento, que serão vistas a seguir. FIGURA 6.7 Heap min-max. FIGURA 6.8 Relações de ordem. Como já acontecia nas listas de prioridades, para retirar o mínimo ou o máximo deve-se substituir o elemento desejado pelo último elemento da tabela e depois “descer” na árvore, conforme o procedimento descer. Obviamente níveis diversos induzem a tratamentos diversos. Seja, por exemplo, a retirada do elemento de menor prioridade, situado na posição i (i = 1, inicialmente), nível mínimo. Após a sua substituição pelo último nó da tabela, a sua prioridade deve ser corrigida. Observa-se, pelas relações (ii) e (iii), que a prioridade do nó i deve ser menor que a de seus filhos e netos. Seja m o índice do menor desses elementos. Considere as hipóteses: sm é filho de si na árvore: neste caso, sm está num nível máximo, e si não tem netos. Se sm < si é suficiente a troca dos dois nós. sm é neto de si na árvore: sm está também num nível mínimo. A troca entre os dois deve ser feita se sm < si.. Entre os níveis mínimos i e m existe um nível máximo que contém o pai sp de sm.. Se sm > sp, as suas posições na lista devem ser trocadas. A nova posição m do nó pode ainda não ser correta. O procedimento descer-min deve ser repetido recursivamente até que isso ocorra. Para a exclusão do elemento de prioridade máxima, basta observar que ele é o maior dentre os filhos da raiz. Seja i