Complexidade de Algoritmos e Análise de Desempenho

Heaps e Heapsort

Última ocorrência: 2023-09-25 em Universidade LaSalle Canoas

Posts Relacionados

Assunto

  1. Heaps
    • Um heap é uma estrutura em árvore que satisfaz uma propriedade do heap.
    • Um maxheap é um heap cuja propriedade a ser satisfeita é
      dado um nó C qualquer, o a chave do nó P, que é pai de C é maior que a chave de C.
    • Um minheap é um heap cuja propriedade a ser satisfeita é
      dado um nó C qualquer, o a chave do nó P, que é pai de C é menor que a chave de C.
    • Heaps são a forma mais eficiente de implementação de filas de prioridade.
    • Uma implementação bastante comum é a de heap binários, que formam árvores binárias quase completas.
    • Operações:
      • find_min/find_max: $O(1)$
      • insert/push: $O(\log{n})$ (heap binário) ou $\Theta(1)$ (amortizado, para outras implementações)
      • delete_min/delete_max/pop: $O(\log{n})$
      • increse_key/decrease_key: $O(\log{n})$ (heap binário) ou $\Theta(1)$ (Fibonacci heap, Brodal queue)
      • meld (junção de dois heaps): $O(n)$ (heap binário), $O(\log{n})$ (Binomial) ou $\Theta(1)$ (outras implementações)
    • Em geral todas implementações de heaps que não sejam heaps binários ou pairing heaps são complicadas de mais e podem ser mais lentas, apesar do tempo de operação teórico parecer melhor.
  2. Heapify
    • Operação de criação de um heap a partir de um array de dados.
    • Utiliza os métodos sift_up e sift_down.
    • sift_up move um elemento para cima no heap
    • sift_down move um elemento para baixo no heap
    • Utilizando o algoritmo de Floyd, apenas o método sift_down é necessário e a complexidade de tempo é $O(n)$
      Começando em $\lfloor\frac{n}{2}\rfloor$ até a raiz, faça sift_down do elemento.
      Para $n/2$ elementos, o esforço é zero.
      Para $n/4$ elementos, o esforço é 1.
      Para $n/8$ elementos, o esforço é 2.
      $\dots$
      Logo, a quantidade de esforço é $n\times\sum_{i=0}^\infty{\frac{i}{2^{i}}} = 2n$, portanto $\Theta(n)$
  3. Representação de um Heap em um array
    • Dado um nó com índice $i$ no array (base 0):
      • Filho Esquerdo: $2i + 1$
      • Filho direito: $2i + 2$
      • Pai: $\lfloor\frac{i-1}{2}\rfloor$
      • Como as operações são sempre realizadas em números inteiros, as multiplicações e divisões são facilmente implementadas com os operadores $\gg$ e $\ll$.
  4. Heapsort
    • Crie um heap máximo.
    • Substitua a raiz do heap pelo último elemento do array
    • Faça sift_down da nova raiz.
    • $n-1$ elementos sofrerão sift_down com custo $\Theta(\log{n})$, logo, o heapsort tem complexidade $O(n\log{n})$

Questões

  1. Projeto: Pesquise e implemente o introsort, o algoritmo de ordenação por comparação não-estável da biblioteca padrão da linguagem de programação C++.