Estrutura de Heap e Algoritmo de Heap Sort: Fundamentos e Código

Fundamentos da Estrutura de Heap

O heap é uma estrutura de dados baseada em uma árvore binária completa que assegura um ordenamento parcial entre os níveis. Em uma configuração de max-heap, cada nó pai possui chave superior ou igual à dos seus filhos; já no modelo min-heap, a relação se inverte, mantendo os valores menores na parte superior. Essa característica hierárquica permite acessar o elemento extremo em tempo constante, sendo amplamente adotada na construção de filas de prioridade e rotinas de classificação estáveis.

Mecanismos de Inserção e Rebalanceamento

A preservação da ordem interna depende de duas operações complemantares: elevação e descida. Ao adicionar um registro, ele é posicionado temporariamente na última índice do vetor subjacente. Se o sistema operar como max-heap, o novo valor é comparamdo recursivamente com seu pai imediato. Caso a condição de ordenamento seja violada, ocorre uma troca de posições, propagando o movimento em direção à raiz até que a propriedade seja restaurada. No cenário min-heap, o fluxo oposto é executado, buscando acomodar valores decrescentes nos níveis superiores através de ajustes sequenciais.

Implementação Operacional

A seguir, apresenta-se uma versão atualizada utilizando classes ES6. A abstração recebe uma função comparadora como parâmetro, eliminando a necessidade de duplicar lógicas e facilitando a alternância entre comportamentos de máximo e mínimo. Os métodos auxiliares gerenciam a reposicionamento dos nós após mutações.

class HeapStructure {
  constructor(comparator = (a, b) => a > b) {
    this.buffer = [];
    this.compare = comparator;
  }

  insert(value) {
    this.buffer.push(value);
    this.siftUp(this.buffer.length - 1);
  }

  extract() {
    if (this.buffer.length === 0) return undefined;
    const extremeValue = this.buffer[0];
    const tailValue = this.buffer.pop();

    if (this.buffer.length > 0) {
      this.buffer[0] = tailValue;
      this.siftDown(0);
    }
    return extremeValue;
  }

  siftUp(idx) {
    while (idx > 0) {
      const parentIdx = Math.floor((idx - 1) / 2);
      if (this.compare(this.buffer[idx], this.buffer[parentIdx])) {
        [this.buffer[idx], this.buffer[parentIdx]] = [this.buffer[parentIdx], this.buffer[idx]];
        idx = parentIdx;
      } else {
        break;
      }
    }
  }

  siftDown(idx) {
    const capacity = this.buffer.length;
    while (true) {
      let target = idx;
      const leftChild = 2 * idx + 1;
      const rightChild = 2 * idx + 2;

      if (leftChild < capacity && this.compare(this.buffer[leftChild], this.buffer[target])) {
        target = leftChild;
      }
      if (rightChild < capacity && this.compare(this.buffer[rightChild], this.buffer[target])) {
        target = rightChild;
      }

      if (target !== idx) {
        [this.buffer[idx], this.buffer[target]] = [this.buffer[target], this.buffer[idx]];
        idx = target;
      } else {
        break;
      }
    }
  }
}

Rodagem do Algoritmo de Classificação

O procedimento de ordenação heap sort utiliza a arquitetura descrita para rearranjar coleções não estruturadas. A primeira fase converte o conjunto original em um heap válido, depositando o item dominante na posição inicial. Posteriormente, executa-se uma rotina de remoção: o vértice superior é permutado com o último membro da coleção, a estrutura é retrátil e o mecanismo de descida é invocado sobre o intervalo remanescente. O ciclo prossegue até que todos os componentes assumam suas posições finais.

// Demonstração de ordenação ascendente
const queueMax = new HeapStructure((x, y) => x < y);

const dataset = [42, 17, 89, 3, 65, 28, 51];
dataset.forEach(item => queueMax.insert(item));

const orderedArray = [];
while (queueMax.buffer.length > 0) {
  orderedArray.push(queueMax.extract());
}

console.log(orderedArray); // Resultado: [3, 17, 28, 42, 51, 65, 89]

Eficácia Temporal e Cenários de Uso

A complexidade assintótica desse método de ordenação permanece O(n log n) independentemente da distribuição inicial dos dados, contornando a degradação observada em estratégias baseadas em particionamento. Para além da organização linear, a arquitetura subsidia escalonadores de tarefas em sistemas operacionais, geração de códigos de compressão Huffman, cálculo de distâncias mínimas em malhas graphísticas e pipelines que requerem captura imediata do próximo evento de maior relevância.

Tags: estrutura-de-dados heap-sort fila-de-prioridade algoritmos-em-javascript árvore-binária-completa

Publicado em 10-9 12:20