Índice
deslocamento da pilha para baixo
Código do arquivo src/runoob/heap/HeapShiftDown.java:
deslocamento da pilha para baixo
Esta seção apresentará como retirar um elemento de um heap máximo, chamado shift down. Somente o elemento com maior prioridade pode ser retirado, ou seja, o nó raiz. Depois de retirar o 62 original, o seguinte descreve como preencher o heap máximo.
Na primeira etapa, colocamos o último dígito do array no nó raiz, o que não satisfaz a definição do heap máximo neste momento.
O processo de ajuste consiste em descer passo a passo o nó raiz 16. 16 é menor que os nós filhos. Primeiro, compare os nós filhos 52 e 30, qual deles é maior, e troque de posição com o maior.
Continue a comparar os nós filhos 28 e 41 de 16, 41 é maior, então 16 e 41 trocam de posição.
Continue comparando 16 com o nó filho 15, 16 é maior, então não há necessidade de trocar agora e, finalmente, nossa operação de deslocamento para baixo está concluída, mantendo a natureza de um heap máximo.
4. Código de exemplo Java
Download do pacote fonte: Baixar https://www.runoob.com/wp-content/uploads/2020/09/runoob-algorithm-HeapShiftDown.zip
Código do arquivo src/runoob/heap/HeapShiftDown.java:
package runoob.heap;
/**
* Retire um elemento do maior heap
*/
public class HeapShiftDown<T extends Comparable> { protected T[] data; protected int count; protected intcapacidade; // Construtor, constrói um heap vazio , pode conter elementos de capacidade public HeapShiftDown(intcapacidade){ //Adicionar 1 aqui refere-se ao número de elementos que podem ser carregados originalmente, depois remover 0 e apenas elementos de capacidade podem ser carregados data = (T[])new Comparable[ capacidade +1]; contagem = 0; this.capacity = capacidade; } // retorna o número de elementos no heap public int size(){ return count; } // retorna um valor booleano indicando se o heap está vazio public boolean isEmpty (){ contagem de retorno == 0;
}
// Insere um novo elemento no item de heap máximo
public void insert(T item){ assert count + 1 <=capacidade; data[count+1] = item; count ++; shiftUp(count); } // Take retira o elemento superior do heap máximo, ou seja, o máximo de dados armazenados no heap public T extractMax(){ assert count > 0; T ret = data[1]; swap( 1 , count ); count --; shiftDown (1 ); return ret; } // Obtém o elemento superior no heap máximo public T getMax(){ assert( count > 0 ); return data[1]; } // Troca os dois elementos com índices i e j em a pilha
private void swap(int i, int j){ T t = dados[i]; dados[i] = dados[j]; dados[j] = t; } //********** * ******** //* Função auxiliar máxima do núcleo do heap //********************** private void shiftUp(int k){ while( k > 1 && data[k/2].compareTo(data[k]) < 0 ){ swap(k, k/2); k /= 2; } } //operação shiftDown private void shiftDown(int k){ while ( 2*k <= count ){ int j = 2*k; // Neste ciclo, data[k] e data[j] trocam de posição if( j+1 <= count && data[j+1] .compareTo( dados[j]) > 0 ) j++;
// data[j] é o valor máximo de data[2*k] e data[2*k+1]
if( data[k].compareTo(data[j]) >= 0 ) break;
swap(k, j);
k = j;
}
System.out.println("end of shiftDown");
}
// Testa HeapShiftDown
public static void main(String[] args) { HeapShiftDown<Integer> heapShiftDown = new HeapShiftDown<Integer>(100 ) ; // Número de elementos no heap int N = 100; // Faixa de valores dos elementos no heap [0, M) int M = 100; for( int i = 0 ; i < N ; i ++ ) heapShiftDown .inserir(new Inteiro((int)(Math. random() * M)) ); Inteiro[] arr = new Inteiro[N];
// Extraia gradualmente os dados no heap máximo usando extractMax
// A ordem de extração deve ser de grande para pequeno
for( int i = 0 ; i < N ; i ++ ){ arr[i ] = heapShiftDown.extractMax() ; System.out.print(arr[i] + " "); } // Certifique-se de que o array arr esteja organizado do maior para o menor for( int i = 1 ; i < N ; i ++ ) assert arr[i- 1] >= arr[i]; } }