Heaps e Filas de Prioridade. Fundamentos 3 Filas de Prioridade Uma fila de prioridade é uma lista...

Preview:

Citation preview

Heaps e Filas de Prioridade

Fundamentos

3

Filas de Prioridade

Uma fila de prioridade é uma lista de itens na qual cada item possui uma prioridade associada.

Pode-se determinar o item que tem a maior e o que tem a menor prioridade, por exemplo.

Itens são inseridos em filas de prioridade em qualquer ordem. A exclusão de itens é feita em ordem decrescente de prioridade.

4

Filas de Prioridade

Filas de prioridade são containers que possuem as seguintes operações: enqueue

colocar objetos no container; findMin (ou findMax)

retornar o objeto de menor prioridade no container dequeueMin ( ou dequeueMax)

remover o menor objeto do container.

Uma fila de prioridades é usada para armazenar um conjunto de chaves de um conjunto ordenado de chaves K.

5

Árvore Binária Perfeita

Definição (Árvore Binária Perfeita) 

Uma árvore binária perfeita de altura h 0, é uma árvore binária {R, TL, TR} com as seguintes propriedades.

1. Se h=0, TL = 0 e TR = 0.

2. Para h>0 tanto TL quanto TR são árvores

binárias perfeitas de altura h-1.

6

Árvore Binária Completa

Definição (Árvore Binária Completa)  Uma árvore binária completa de altura h 0, é uma árvore binária {R, TL, TR} com as seguintes propriedades.

1. Se h=0, TL = 0 e TR = 0.

2. Para h>0 existem duas possibilidades1. TL é uma árvore binária perfeita de altura h-1 e TR é uma

árvore binária completa de altura h-1; ou

2. TL é uma árvore binária completa de altura h-1 e TR é uma

árvore binária perfeita de altura h-2.

7

Exemplo de árvores perfeitas e completas

8

Árvore N-aria Completa

Definição (Árvore N-aria Completa)  Uma árvore N-aria completa de altura h 0, é uma árvore N-aria {R, T0, T1, T2, ... TN-1} com as seguintes propriedades.

1. Se h=0, T1 = para todo i, 0 i < N. 2. Para h>0 existe um j, 0 j < N tal que

1. Ti é uma árvore N-aria perfeita de altura h-1 para todo i: 0 i < j;

2. Tj é uma árvore N-aria completa de altura h-1;

3. Ti é uma árvore N-aria perfeita de altura h-2 para todo i:j<i<N.

9

Árvore N-aria completa

Uma árvore completa é uma árvore na qual todos os níveis estão cheios exceto o último e este nível é cheio da esquerda para a direita.

10

Heap

As implementações de filas de prioridade são baseadas em um tipo especial de árvore chamado de heapHá dois tipos de heap (min e max)Definição ((Min) Heap)  Um (Min) Heap   é uma árvore, {R, T0, T1, T2, ... TN-1} com as seguintes propriedades:

1. Cada sub árvore de T é um heap, 2. A raiz de T é menor ou igual do que a raiz de cada sub

árvore de T. Ou seja, R Ri para todo i, 0 i n , aonde Ri é a raiz de Ti.

11

Heap Binário

Um heap binário é uma árvore binária ordenada que tem a forma de árvore completa.

Um heap binário pode ser implementado sobre um “array”, o que dispensa o armazenamento de ponteiros para a montagem da árvore.

12

Incluir Itens em um Heap Binário Como o heap resultante da inclusão deve ser uma árvore completa só existe um local para a inclusão.Para incluir o item de chave 2 no heap da figura verifica-se a posição da inclusão (figura (a) ). A seguir reajusta-se o heap até chegar à posição adequada (figuras (b) e (c)). Finalmente faz-se a inclusão (figura (d)).

13

Remover Itens de um Heap Binário

O menor dos itens está sempre na raiz de um heap mínimo.

A última linha do heap deve ser esvaziada da direita para a esquerda na remoção de itens.

O dado a ser removido está na raiz mas o nó a ser removido está em folha.

14

Exemplo de HeapNo heap da figura a operação dequeueMin remove a chave 2 do heap mas o nó contendo 6 é que deve ser removido.O buraco deixado pela remoção da raiz deve ser reposicionado no heap, descendo até permitir a reinserção na árvore da chave 6 que ocupava a posição do heap a ser eliminadaPara afastar da raiz um buraco este troca de lugar com o menor de seus dois filhos.O processo continua até o buraco atingir uma folha da árvore ou uma posição adequada à chave que necessita ser reposicionada na árvore.

Implementação Java

16

Implementação

17

Interface PriorityQueue

// pgm11_01.txt

public interface PriorityQueue

extends Container

{

void enqueue (Comparable object);

Comparable findMin ();

Comparable dequeueMin ();

}

18

Interface MergeablePriorityQueue

// pgm11_02.txt

public interface MergeablePriorityQueue

extends PriorityQueue

{

void merge (MergeablePriorityQueue queue);

}

19

Campos de BinaryHeap

// pgm11_03.txt

public class BinaryHeap

extends AbstractContainer

implements PriorityQueue

{

protected Comparable[] array;

// ...

}

20

Métodos Construtor e purge da classe

BinaryHeap

// pgm11_04.txtpublic class BinaryHeap extends AbstractContainer implements PriorityQueue{ protected Comparable[] array;

public BinaryHeap (int length){ array = new Comparable[length + 1]; }

public void purge () {

while (count > 0) array [count--] = null;

} // ...}

21

Método enqueue da classe BinaryHeap

• Como o heap resultante da inclusão deve ser uma árvore completa só existe um local para a inclusão

• Este local (vazio ou buraco) vai “subir” no heap até encontrar seu ligar, deixando para baixo os valores menores do que o objeto o incluir no heap

• A “subida” no heap é feita buscando-se a posição do array obtida da divisão por dois da posição corrente

• Quando o buraco parar de “subir” nele inclui-se o objeto

22

Método enqueue da classe BinaryHeap

// pgm11_05.txt public void enqueue (Comparable object) {

if (count == array.length - 1) throw new ContainerFullException ();++count;int i = count;while (i > 1 && array [i/2].isGT (object)){ array [i] = array [i / 2]; i /= 2;}array [i] = object;

}

23

Método findMin da classe BinaryHeap

// pgm11_06.txtpublic class BinaryHeap extends AbstractContainer implements PriorityQueue{ protected Comparable[] array;

public Comparable findMin () {

if (count == 0) throw new ContainerEmptyException ();return array [1];

} // ...}

24

Método dequeue da classe BinaryHeap

O elemento a ser removido é o da raiz do heapO objeto que estava no último nó do heap deve procurar seu lugar no heap pois esse nó vai desaparecerInicia-se pela raiz, agora vazia, testando-se seus dois filhos para verificar o menorSe o objeto que estava no último nó for menor que os filhos da raiz termina a repetiçãoCaso contrário a raiz (objeto que estava no último nó) troca de lugar com o menor de seus dois filhos e passa a ser a raiz do heap corrente a pesquisarQuando a repetição termina a raiz no heap corrente recebe o objeto que estava no último nó

25

Método dequeue da classe BinaryHeap public Comparable dequeueMin () {

if (count == 0) throw new ContainerEmptyException ();Comparable result = array [1];Comparable last = array [count];--count;int i = 1;while (2 * i < count + 1){ int child = 2 * i; if (child + 1 < count + 1

&& array [child + 1].isLT (array [child]))child += 1;

if (last.isLE (array [child]))break;

array [i] = array [child]; i = child;}array [i] = last;return result;

}

Exemplos

27

Exemplos

Serão apresentados dois exemplos de uso de Filas de Prioridade

O primeiro exemplo é absolutamente trivial com inclusão e exclusão de objetos manualmente, via teclado

O segundo exemplo consiste em uma simulação de eventos discretos

28

Exemplo de uso de Fila de Prioridade em simples entrada e saída de dados

Exemplo usando o teclado para inserir dados inteiros em uma fila de prioridade

O usuário recebe um “prompt” para escolher entre inserir, remover dados, listas a fila de prioridade ou encerrar o programa

Caso escolha a inserção o usuário deve entrar com o dado

29

Composição do código

A hierarquia de classes já foi apresentada no estudo da classe BinaryHeap

Serão apresentadas as classes específicas desta aplicação Classe de Dados Classe da Aplicação Fila de Prioridade

30

Classe de Dados (1)import cap5.*;

import java.io.*;

public class DataAreaextends AbstractObjectimplements Serializable{ private String numero; private String transacao; final private int TAMANHO_INT = 2; public DataArea() { this.numero = ""; } public DataArea( String numero) { if ( numero.length() < TAMANHO_INT ) { numero = "0"+numero; } this.numero = numero; }

31

Classe de Dados (2)public DataArea( BufferedReader br )

throws IOException { int i = 0; String s, line = br.readLine(); if ( line == null ) { transacao = "err"; return; } transacao = line.substring(i,1);

i = 2;

if ( transacao.compareToIgnoreCase( "i" ) == 0 ){ numero = line.substring(i,i+TAMANHO_INT); i += TAMANHO_INT+1; nome = line.substring(i,i+TAMANHO_NOME); i += TAMANHO_NOME+2; s = line.substring(i,line.length()); salario = Double.parseDouble( s ); }

}

32

Classe de Dados (3) public String getNumero() { return numero; }

public String getTransacao() { return transacao; } public void setNumero( String numero ) { this.numero = numero; } } public void imprime() { System.out.println ("Numero = " + numero ); } protected int compareTo (cap5.Comparable object) {

DataArea arg = (DataArea) object;return numero.compareToIgnoreCase( arg.numero );

}}

33

FilaPrioridade01 (1)import cap5.*;import dados.*;

import java.io.*;import corejava.*;

public class FilaPrioridade01{ private static void lerDados( PriorityQueue listaP ) {

DataArea data = null;String transacao = "ok";

try { BufferedReader br = new BufferedReader( new FileReader("xxxx.zzz") );

while ( transacao.compareToIgnoreCase( "err" ) != 0 ){ data = new DataArea( br ); transacao = data.getTransacao(); if ( transacao.compareToIgnoreCase( "i" ) == 0 ) stack.push( data ); }br.close();}

catch(Exception e){}

}

34

FilaPrioridade01 (2)

public static void main (String[] args){ String numero; DataArea data; Enumeration todos;

PriorityQueue filaP = new LeftistHeap(); lerDados( listaP );

boolean continua = true; while (continua) { System.out.println('\n' + “==================");

System.out.println('\n' + "O que deseja fazer?");System.out.println('\n' + "1. Inserir");System.out.println("2. Remover");System.out.println("3. Listar");System.out.println("4. Sair");

35

FilaPrioridade01 (3)

int opcao = Console.readInt('\n' + "Digite um número entre 1 e 4:");switch (opcao) { case 1:

{ numero = Console.readLine('\n' + "Digite o numero: "); data = new DataArea (numero);

filaP.enqueue(data); System.out.println('\n' + "Inserido com sucesso!"); break; }case 2: // Remover { data = (DataArea) filaP.dequeue(); System.out.println('\n' + data.getNumero()+

" removido com sucesso!"); break;

}

36

FilaPrioridade01 (4)case 3: // Listar tudo

{ todos = filaP.getEnumeration(); while (todos.hasMoreElements ())

{ System.out.println(""); data = (DataArea)todos.nextElement();

data.imprime(); }break;

}case 4: // Sair

break;

default:System.out.println('\n' + "Opção inválida!");

} } }}

37

Exemplo de uso de Fila de Prioridade em Simulação de Eventos Discretos

Uma simulação de eventos discretos servirá para ilustrar um emprego das filas de prioridade

Etapas da simulação Geração do modelo matemático Programa para avaliação do modelo

Sistemas possuem: Estados Eventos (mudanças de estado)

38

Ambiente escolhido para a simulação

Atendimento a clientes em um caixa de banco

O estado do sistema pode ser caracterizado por: Estado do atendente de caixa (ocupado,

desocupado) Número de clientes na fila

39

Modelo de fila de banco

40

Características do Modelo

Eventos Tipo

Chegada (arrival) Partida (departure)

Tempo

Association (utilizada para fazer comparações de prioridade com um atributo chave em vez de com todo o objeto) Tempo (chave) Tipo (valor)

41

Implementação do exemplo (1)

Simulação de sistema composto de: Fila Atendente

A classe Event representa os eventos em simulação

Uma fila de prioridade simulará o atendimento e a prioridade será por tempo

42

Implementação do exemplo (2)

A classe Simulation contém uma fila de prioridade eventList que armazena os eventos

O estado do sistema é retratado pelas variáveis: serverBusy (atendente ocupado sim/não ?) numberInQueue (número de clientes

aguardando atendimento)

43

Implementação do exemplo (3)O método run implementa a simulação e recebe um argumento timeLimit (tempo total da simulação)A chegada de clientes será modelada por instâncias da classe ExponentialRV (geradora de pseudo aleatórios): serviceTime (tempo de um atendimento) interArrivalTime (intervalo entre chegaadas)

A interface RandomVariable tem o método nextDouble que busca um novo valor que neste exemplo teve distribuição com média 100 para ambas as variáveis

44

Implementação do exemplo (4)

Fila inicialmente vazia

Um cliente chega no tempo zero

Repetição até que a lista de eventos fique vazia

Cada iteração retira um elemento da fila de prioridade

Quando o tempo do evento a ser atendido ultrapasse timeLimit termina a simulação

Os eventos podem ser de chegada ou de partida

45

Implementação do exemplo (5)

Atendente desocupado torna-se ocupado na chegada de um cliente disparando o gerador de tempo de atendimento e calculando o tempo de saída correspondente

Atendente ocupado faz aumentar numberInQueue

Depois de cada chegada dispara o gerador de tempo para nova chegada

46

Implementação do exemplo (6)

Evento de saída e fila vazia tornam atendente desocupado

Evento de saída e fila não vazia chamam o próximo na fila disparando o gerador de tempo de atendimento e calculando o tempo de saída correspondente

47

Lembrete: Classe Associationpublic class Association extends AbstractObject{ protected Comparable key; protected Object value; public Association (Comparable key, Object value) {

this.key = key;this.value = value;

} public Association (Comparable key)

{ this (key, null); } public Comparable getKey ()

{ return key; } public Object getValue ()

{ return value; } protected int compareTo (Comparable object) {

Association association = (Association) object;return key.compare (association.getKey ());

}}

48

Classe Event// pgm11_22.txtpublic class Simulation{ static class Event

extends Association {

public static final int arrival = 0;public static final int departure = 1;

Event (int type, double time) { super (new Dbl (time), new Int (type)); }

double getTime () { return ((Dbl) getKey ()).doubleValue (); }

int getType () { return ((Int) getValue ()).intValue (); }

} }

49

Classe Simulation: Inicialização

// pgm11_23.txtpublic class Simulation{ PriorityQueue eventList = new LeftistHeap ();

public void run (double timeLimit) {

boolean serverBusy = false;int numberInQueue = 0;RandomVariable serviceTime = new ExponentialRV (100.);RandomVariable interArrivalTime = new ExponentialRV (100.);eventList.enqueue (new Event (Event.arrival, 0));

50

Classe Simulation: Tratamento do evento de chegadawhile (!eventList.isEmpty ()){ Event event = (Event) eventList.dequeueMin (); double t = event.getTime (); if (t > timeLimit)

{ eventList.purge (); break; } switch (event.getType ()) { case Event.arrival:

if (!serverBusy){ serverBusy = true; eventList.enqueue (new Event(Event.departure,

t + serviceTime.nextDouble ()));}else ++numberInQueue;eventList.enqueue (new Event (Event.arrival, t + interArrivalTime.nextDouble ()));break;

51

Classe Simulation: Tratamento do evento de partida

case Event.departure:if (numberInQueue == 0) serverBusy = false;else{ --numberInQueue; eventList.enqueue (new Event(Event.departure,

t + serviceTime.nextDouble ()));}break;

}}

} // ...}

Implementação C++

53

Implementação

54

Definições das Classes PriorityQueue e MergeablePriorityQueue

// pgm11_01.cpp

class PriorityQueue : public virtual Container

{

public:

virtual void Enqueue(Object&) = 0;

virtual Object& FindMin() const = 0;

virtual Object& DequeueMin() = 0;

};

class MergeablePriorityQueue : public virtual PriorityQueue

{

public:

virtual void Merge(MergeablePriorityQueue&) = 0;

};

55

Definição da Classe BinaryHeap

// pgm11_02.cpp

class BinaryHeap : public PriorityQueue

{

Array<Object*> array;

public:

BinaryHeap(unsigned int);

~BinaryHeap();

// ...

};

56

Definições da Função Membro Purge e do Construtor e Destrutor da Classe BinaryHeap

// pgm11_03.cppBinaryHeap::BinaryHeap(unsigned int length) :

array(length, 1){}

void BinaryHeap::Purge(){

if(IsOwner ()){

for(unsigned int i = 1; i < count + 1; ++i)delete array[i];

}count = 0;

}BinaryHeap::~BinaryHeap()

{ Purge (); }

57

Método enqueue da classe BinaryHeap

• Como o heap resultante da inclusão deve ser uma árvore completa só existe um local para a inclusão

• Este local (vazio ou buraco) vai “subir” no heap até encontrar seu ligar, deixando para baixo os valores menores do que o objeto o incluir no heap

• A “subida” no heap é feita buscando-se a posição do array obtida da divisão por dois da posição corrente

• Quando o buraco parar de “subir” nele inclui-se o objeto

58

Definição da Função Membro Enqueue da Classe BinaryHeap

// pgm11_04.cpp

void BinaryHeap::Enqueue(Object& object)

{

if(count == array.Length())

throw domain_error("priority queue is full");

++count;

unsigned int i = count;

while(i > 1 && *array[i / 2] > object)

{

array[i] = array[i / 2];

i /= 2;

}

array[i] = &object;

}

59

Definição da Função membro FindMin

// pgm11_05.cpp

Object& BinaryHeap::FindMin() const

{

if(count == 0)

throw domain_error("priority queue is empty");

return *array[1];

}

60

Método dequeue da classe BinaryHeap

O elemento a ser removido é o da raiz do heapO objeto que estava no último nó do heap deve procurar seu lugar no heap pois esse nó vai desaparecerInicia-se pela raiz, agora vazia, testando-se seus dois filhos para verificar o menorSe o objeto que estava no último nó for menor que os filhos da raiz termina a repetiçãoCaso contrário a raiz recebe o menor de seus dois filhos que passa a ser a raiz do heap corrente a pesquisarQuando a repetição termina a raiz no heap corrente recebe o objeto que estava no último nó

61

Definição da Função Membro DequeueMin da Classe BinaryHeap (1)

// pgm11_06.cppObject& BinaryHeap::DequeueMin(){

if(count == 0)throw domain_error("priority queue is empty");

Object& result = *array[1];Object& last = *array[count];--count;unsigned int i = 1;

62

Definição da Função Membro DequeueMin da Classe BinaryHeap (2)

while(2 * i < count + 1){

unsigned int child = 2 * i;if(child + 1 < count + 1 && *array[child + 1]

< *array[child])

child += 1;if(last <= *array[child])

break;array[i] = array[child];i = child;

}array[i] = &last;return result;

}

63

Definição da Classe LeftistHeap

// pgm11_07.cppclass LeftistHeap :

public BinaryTree,public MergeablePriorityQueue

{unsigned int nullPathLength;void SwapContents(LeftistHeap&);

public:LeftistHeap();LeftistHeap(Object&);LeftistHeap& Left() const;LeftistHeap& Right() const;void Merge(MergeablePriorityQueue&);// ...

};

64

Definição da Função Membro Merge da Classe LeftistHeap

// pgm11_08.cppvoid LeftistHeap::Merge(MergeablePriorityQueue& queue){

LeftistHeap& arg = dynamic_cast<LeftistHeap&> (queue);if(IsEmpty ())

SwapContents(arg);else

if(!arg.IsEmpty()){

if(*key > *arg.key)SwapContents(arg);

Right().Merge(arg);if(Left().nullPathLength < Right().nullPathLength)

Swap(left, right);nullPathLength = 1 + Min(Left().nullPathLength,

Right().nullPathLength);}

}

65

Definição da Função Membro Enqueue da Classe LeftistHeap

// pgm11_09.cpp

void LeftistHeap::Enqueue(Object& object)

{

LeftistHeap heap(object);

Merge(heap);

}

66

Definição da Função Membro FindMin da Classe LeftistHeap

// pgm11_10.cpp

Object& LeftistHeap::FindMin() const

{

if(IsEmpty ())

throw domain_error("priority queue is empty");

return *key;

}

67

Definição da Função Membro DequeueMin da Classe LeftistHeap// pgm11_11.cppObject& LeftistHeap::DequeueMin(){

if(IsEmpty())throw domain_error("priority queue is empty");

Object& result = *key;LeftistHeap& oldLeft = Left();LeftistHeap& oldRight = Right();key = 0;left = 0;right = 0;SwapContents(oldLeft);delete &oldLeft;Merge(oldRight);delete &oldRight;return result;

}

68

Definição da Classe BinomialTree

// pgm11_12.cpp

class BinomialTree : public GeneralTree

{

void SwapContents(BinomialTree&);

public:

BinomialTree(Object&);

void Add(BinomialTree&);

BinomialTree& Subtree(unsigned int) const;

};

69

Definição da Função Membro Add da Classe BinomialTree

// pgm11_13.cpp

void BinomialTree::Add(BinomialTree& tree)

{

if(degree != tree.degree)

throw invalid_argument("incompatible degrees");

if(*key > *tree.key)

SwapContents(tree);

AttachSubtree(tree);

}

70

Definição da Classe BinomialQueue

// pgm11_14.cppclass BinomialQueue : public MergeablePriorityQueue{

LinkedList<BinomialTree*> list;BinomialTree& FindMinTree() const;void AddTree(BinomialTree&);void RemoveTree(BinomialTree&);static BinomialTree* Sum( BinomialTree*,

BinomialTree*, BinomialTree*);static BinomialTree* Carry( BinomialTree*,

BinomialTree*, BinomialTree*);

public:BinomialQueue();~BinomialQueue();// ...

};

71

Definições da Função Membro AddTree e RemoveTree da Classe BinomialQueue

// pgm11_15.cpp

void BinomialQueue::AddTree(BinomialTree& tree)

{

list.Append(&tree);

count += tree.Count();

}

void BinomialQueue::RemoveTree(BinomialTree& tree)

{

list.Extract(&tree);

count -= tree.Count();

}

72

Definições da Função Membro FindMinTree e FindMin da Classe BinomialHeap// pgm11_16.cppBinomialTree& BinomialQueue::FindMinTree() const{

ListElement<BinomialTree*> const* ptr;BinomialTree* minTree = 0;for(ptr = list.Head(); ptr != 0; ptr = ptr->Next()){

BinomialTree* tree = ptr->Datum();if(minTree == 0 || tree->Key() < minTree->Key())

minTree = tree;}return *minTree;}Object& BinomialQueue::FindMin() const

{if(count == 0)

throw domain_error("priority queue is empty");return FindMinTree().Key();

}

73

Definição da Função Membro Merge da Classe BinomialQueue (1)

// pgm11_17.cppvoid BinomialQueue::Merge(MergeablePriorityQueue& queue){

BinomialQueue& arg = dynamic_cast<BinomialQueue&> (queue);LinkedList<BinomialTree*> oldList = list;list.Purge();count = 0;ListElement<BinomialTree*> const* p = oldList.Head();ListElement<BinomialTree*> const* q = arg.list.Head();BinomialTree* carry = 0;

74

Definição da Função Membro Merge da Classe BinomialQueue (2)for(unsigned int i = 0; p || q || carry; ++i) {

BinomialTree* a = 0;if(p && p->Datum()->Degree() == i) {

a = p->Datum();p = p->Next();

}BinomialTree* b = 0;if(q && q->Datum()->Degree() == i) {

b = q->Datum();q = q->Next();

}BinomialTree* sum = Sum(a, b, carry);if(sum)

AddTree(*sum);carry = Carry(a, b, carry);

}arg.list.Purge();arg.count = 0;

}

75

Definições da Função Membro Sum e Carry da Classe BinomialQueue (1)

// pgm11_18.cppBinomialTree* BinomialQueue::Sum( BinomialTree* a,

BinomialTree* b, BinomialTree* c)

{if(a && !b && !c)

return a;else if(!a && b && !c)

return b;else if(!a && !b && c)

return c;else if(a && b && c)

return c;else

return 0;}

76

Definições da Função Membro Sum e Carry da Classe BinomialQueue (2)

BinomialTree* BinomialQueue::Carry( BinomialTree* a, BinomialTree*

b, BinomialTree*

c){

if(a && b && !c){

a->Add(*b);return a;

}else if(a && !b && c)

{a->Add(*c);return a;

}

77

Definições da Função Membro Sum e Carry da Classe BinomialQueue (3)

else if(!a && b && c) {

b->Add(*c);return b;

}else if(a && b && c)

{a->Add(*b);return a;

}else

return 0;}

78

Definição da Função Membro Enqueue da Classe BinomialQueue

// pgm11_19.cpp

void BinomialQueue::Enqueue(Object& object)

{

BinomialQueue queue;

queue.AddTree(*new BinomialTree(object));

Merge(queue);

}

79

Definição da Função Membro DequeueMin da Classe BinomialQueue (1)

// pgm11_20.cppObject& BinomialQueue::DequeueMin(){

if(count == 0)throw domain_error("priority queue is empty");

BinomialTree& minTree = FindMinTree();RemoveTree(minTree);

BinomialQueue queue;while(minTree.Degree() > 0){

BinomialTree& child = minTree.Subtree(0);minTree.DetachSubtree(child);queue.AddTree(child);

}Merge(queue);

80

Definição da Função Membro DequeueMin da Classe BinomialQueue (2)

Object& result = minTree.Key();

minTree.RescindOwnership();

delete &minTree;

return result;

}

Recommended