40
Ordenação: HeapSort Prof. Túlio Toffolo http://www.toffolo.com.br BCC202 – Aula 17 Algoritmos e Estruturas de Dados I 2014-01 – Aula 16 – Fila de Prioridade / HeapSort Adaptado por Reinaldo Fortes para o curso de 2014-01 Arquivo original: Aula 17: HeapSort

Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

  • Upload
    lyduong

  • View
    226

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

Ordenação: HeapSort

Prof. Túlio Toffolohttp://www.toffolo.com.br

BCC202 – Aula 17

Algoritmos e Estruturas de Dados I

2014-01 – Aula 16 – Fila de Prioridade / HeapSortAdaptado por Reinaldo Fortes para o curso de 2014-01Arquivo original: Aula 17: HeapSort

Page 2: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

FILAS DE PRIORIDADE

Page 3: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

Fila de Prioridade

• É uma estrutura de dados onde a chave de cada item reflete sua habilidade relativa de abandonar o conjunto de itens rapidamente.

• Aplicações:• SOs usam filas de prioridades, nas quais as chaves

representam o tempo em que eventos devem ocorrer.• Métodos numéricos iterativos são baseados na

seleção repetida de um item com maior (menor) valor.• Sistemas de gerência de memória usam a técnica de

substituir a página menos utilizada na memória principal por uma nova página.

3

Page 4: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

TAD - Fila de Prioridade

• Operações:1. Constrói uma fila de prioridades a partir de um

conjunto com n itens.

2. Informa qual é o maior item do conjunto.

3. Retira o item com maior chave.

4. Insere um novo item.

5. Aumenta o valor da chave do item i para um novo valor que é maior que o valor atual da chave.

4

OBS: Neste ponto, estamos considerando que item com maior chave tem maior prioridade.

Page 5: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

TAD - Fila de Prioridade

• Operações:6. Substitui o maior item por um novo item, a não ser

que o novo item seja maior.

7. Altera a prioridade de um item.

8. Remove um item qualquer.

9. Agrupar duas filas de prioridades em uma única.

5

OBS: Neste ponto, estamos considerando que item com maior chave tem maior prioridade.

Page 6: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

Filas de Prioridades - Representação

• Lista linear ordenada:• Constrói é O(n log n) ou O(n2).• Insere é O(n).• Retira é O(1).• Altera é O(n).

• Lista linear não ordenada:• Constrói é O(n).• Insere é O(1).• Retira é O(n).• Altera é O(n)

6

Page 7: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

FILA DE PRIORIDADE:

HEAP

Page 8: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

Heap

• A melhor representação de uma fila de prioridade é através de uma estrutura de dados chamada heap:• Neste caso, Constrói é O(n).• Insere, Retira, Substitui e Altera são O(log n).

• Observação:• Para implementar a operação Agrupar de forma

eficiente e ainda preservar um custo logarítmico para as operações Insere, Retira, Substitui e Altera é necessário utilizar estruturas de dados mais sofisticadas, tais como árvores binomiais (Vuillemin, 1978).

8

Page 9: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

Heap

• É uma árvore binária em que um nó filho é sempre maior ou igual a um nó pai.

• Ou seja: chave(v) >= chave(pai(v))

9

2

65

79 nó raiz (menor elemento)

Page 10: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

Heap

• Árvore binária completa:• Os nós são numerados de 0 a n-1.• O primeiro nó é chamado raiz.• O nó (k-1)/2 é o pai do nó k, para 0 < k < n.• Os nós 2k+1 e 2k+2 são os filhos à esquerda e à

direita do nó k, para 0 < k <= n/2 (mais detalhes a seguir).

10

Page 11: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

Heap

• Cada nó possui uma tupla (chave, elemento)• Assim, cada nó do heap armazena todo o item sendo

armazenado

11

(2, Sue)

(6, Mark)(5, Pat)

(9, Jeff)

(7, Anna)

Page 12: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

Heaps

• As chaves na árvore satisfazem à condição do heap.

• A chave em cada nó é menor do que as chaves em seus filhos.

• A chave no nó raiz é a menor chave do conjunto.

• Uma árvore binária completa pode ser representada por um array:

12

0 1 2 3 4 5 6

2 5 6 9 7 8 10

Page 13: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

Heaps

• A representação é extremamente compacta.

• Permite caminhar pelos nós da árvore facilmente.• Os filhos de um nó i estão nas posições: 2i+1 e 2i+2.• O pai de um nó i está na posição (i-1) div 2.

• Na representação do heap em um arranjo, a menor (ou maior) chave está sempre na posição 0 do vetor.• Heap mínimo: menor elemento na raiz.• Heap máximo: maior elemento na raiz.

13

Page 14: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

HEAP

OPERAÇÕES

Page 15: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

Construção do Heap

• Um algoritmo elegante para construir o heap foi proposto por Floyd em 1964.

• O algoritmo não necessita de nenhuma memória auxiliar.

• Dado um vetor A[0], A[1], ..., A[n-1]:• Os itens A[n/2], A[n/2 + 1], ..., A[n-1] formam um

heap válido pois são nós folhas (nós que não possuem filhos).

• Neste intervalo não existem dois índices i e j tais que j = 2i+1 ou j = 2i+2.

15

Page 16: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

Construção do Heap

16

0 1 2 3 4 5 6

9 5 6 8 3 2 7

9 5 2 8 3 6 7

9 3 2 8 5 6 7

2 3 9 8 5 6 7

2 3 6 8 5 9 7

Vetor inicial

Esq = 2

Esq = 1

Esq = 0

Esq = 0

Page 17: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

Construção do Heap

• Os itens de A[3] a A[6] formam um heap.• O heap é estendido para a esquerda (Esq = 2),

englobando o item A[2], pai dos itens A[5] e A[6].• A condição de heap é violada:

• O heap é refeito trocando os itens A[2] e A[5].

• O item 5 (A[1]) é incluindo no heap (Esq = 1)• A condição de heap é violada:

• O heap é refeito trocando os itens A[1] e A[4].

17

Page 18: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

Construção do Heap

• O item 9 (A[0]) é incluindo no heap (Esq = 0)• A condição de heap é violada:

• O heap é refeito trocando os itens A[0] e A[1].

• Como a condição ainda está sendo violada:• O heap é refeito trocando os itens A[1] e A[4].

• Como resultado, o heap foi construído:• 2 3 6 8 5 9 7

18

Page 19: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

Inserir um Nó no Heap

19

2

65

79

Nó sendo inserido

2

65

79 1

z

z

Comparar o nó inserido com

os pais e trocar enquanto

ele for menor que o pai ou

até que ele seja o nó raiz

Page 20: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

Inserir um Nó no Heap

• Na pior das hipóteses o custo de uma inserção será O(n log n), equivalente à altura da árvore

20

1

25

79 6z

2

15

79 6z

Page 21: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

Remover um Nó do Heap

21

Trocar o nó raiz pelo

último nó do heap e

remover o último nó

2

65

79

último Nó

w

7

65

9

w

novo último Nó

Page 22: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

Remover um Nó do Heap

• Refazer o heap!

• Na pior das hipóteses o custo de uma remoção será O(n log n), equivalente à altura da árvore

22

7

65

9

w 5

67

9

w

Page 23: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

ORDENAÇÃO USANDO HEAP

HEAPSORT

Page 24: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

Ordenação usando Filas de Prioridades

• As operações das filas de prioridades podem ser utilizadas para implementar algoritmos de ordenação.

• Basta utilizar repetidamente a operação Insere para construir a fila de prioridades.

• Em seguida, utilizar repetidamente a operação Retira para receber os itens na ordem correta.

• O uso de heap para fazer a ordenação origina o método HeapSort.

24

Page 25: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

Heapsort

• Para reduzir o número de operações, será utilizado um Heap em que o maior valor é armazenado na raiz• Teremos que o valor de um nó pai deverá ser sempre

maior ou igual aos valores dos seus filhos

• Utilizaremos repetidamente a operação Insere para construir a fila de prioridades.

• Em seguida, utilizaremos repetidamente a operação Retira para receber os itens na ordem inversa.

25

Page 26: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

HeapSort

• Algoritmo:1. Construir o heap.

2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1.

3. Use o procedimento Refaz para reconstituir o heap para os itens A[0], A[1], ..., A[n - 2].

4. Repita os passos 2 e 3 com os n - 1 itens restantes, depois com os n - 2, até que reste apenas um item.

26

Page 27: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

HeapSort

• Exemplo de aplicação do Heapsort:• Link para o arquivo.

27

Page 28: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

HEAPSORT

IMPLEMENTAÇÃO

Page 29: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

void heapRefaz(TItem *v, int esq, int dir) { int i = esq; int j = i*2 + 1; // j = prim eiro filho de i TItem aux = v[i]; // aux = no i (pai de j) w hile (j < = dir) { if (j < dir && v[j].chave < v[j+ 1].chave) j+ + ; // j recebe o outro filho de i if (aux.chave > = v[j].chave) break; // heap foi refeito corretam ente v[i] = v[j]; i = j; j = i*2 + 1; // j = prim eiro filho de i } v[i] = aux;}

HeapSort

29

Page 30: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

void heapConstroi(TItem *v, int n) { int esq; esq = (n / 2) – 1; // esq = nó anterior ao prim eiro nó folha do heap w hile (esq > = 0) { heapRefaz(v, esq, n-1); esq--; }}

HeapSort

30

Page 31: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

void heapSort(TItem *v, int n) { TItem aux; heapConstroi(v, n); w hile (n > 1) { aux = v[n-1]; v[n-1] = v[0]; v[0] = aux; n--; heapRefaz(v, 0, n-1); // refaz o heap }}

HeapSort

31

Page 32: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

MERGESORT

ANÁLISE DO ALGORITMO

Page 33: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

Heapsort

• O procedimento Refaz gasta cerca de log n operações, no pior caso.

• Constroi – executa O(n) x Refaz• Loop interno – executa O(n) x Refaz• Logo, Heapsort gasta um tempo de execução O(n

log n) no pior caso.

33

Page 34: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

Análise do HeapSort

• A altura h da árvore de execução é O(log n)

• Refazer o heap, na pior das hipóteses, tem custo igual à altura da árvore. Construir o heap custa O(n log n)

• Logo: algoritmo é O(n log n)

34

h = O(log n)

Page 35: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

MERGESORT

VANTAGENS/DESVANTAGENS

Page 36: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

Quando usar o Heapsort?

• O HeapSort é recomendado:• Para aplicações que não podem tolerar eventualmente

um caso desfavorável.• Não é recomendado para arquivos com poucos

registros, por causa do tempo necessário para construir o heap.

36

Page 37: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

Heapsort

• Vantagens:• O comportamento do Heapsort é sempre O(n log n),

qualquer que seja a entrada.

• Desvantagens:• O anel interno do algoritmo é bastante complexo se

comparado com o do Quicksort.• O Heapsort não é estável.

37

Page 38: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

Perguntas?

38

Page 39: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

HEAPSORT

EXERCÍCIO

Page 40: Ordenação: HeapSort - DECOM-UFOP · HeapSort • Algoritmo: 1. Construir o heap. 2. Troque o item na posição 1 do vetor (raiz do heap) com o item da posição n-1. 3. Use o procedimento

Exercício

• Dada a sequência de números:

3 4 9 2 5 1 8

Ordene em ordem crescente utilizando o algoritmo HeapSort, apresentado a sequência dos números e explicando cada passo do algoritmo.

40