// Heapify: // Garante a manutenção da propriedade ordem do Heap; complexidade O(log n) void ajustarHeap(TTAD* t, int pai, int posUltimo){ TDadoTAD *d = t->dado; TArrayDinamico *vet = d->vetorFila; void *aux; int esq, dir, posAtual; esq = 2*pai + 1; dir = esq + 1; posAtual = pai; // se o filho esquerdo existir então o direito pode ou não exisitr. if( esq <= posUltimo ){ if( COMPARAR_PRIORIDADES(vet->acessar(vet, esq), vet->acessar(vet, posAtual)) ) posAtual = esq; // atualiza a posição que posição o maior valor if( (dir <= posUltimo) && COMPARAR_PRIORIDADES(vet->acessar(vet, dir), vet->acessar(vet, posAtual)) ) posAtual = dir; // atualiza a posição que posição o maior valor } if(posAtual != pai){ aux = vet->acessar(vet, pai); vet->atualizar(vet, pai, vet->acessar(vet, posAtual)); vet->atualizar(vet, posAtual, aux); t->movimentacoes_desenfileirar++; ajustarHeap(t, posAtual, posUltimo); } }
/** * Método que monta uma Heap no array dado. * *@param *numeros = ponteiro para um array de int no qual ira ser montada a Heap. *@param tamanho = inteiro contendo a quantidade de elementos do array. */ void HeapSort::montarHeap(int *numeros, int tamanho) { for(int i=(tamanho/2)-1;i>=0;i--){ ajustarHeap(numeros,i,tamanho); } }
/** * Método no qual esta implementado o algoritmo do HeapSort, se encarrega de fazer a ordenação. * *@param *numeros = ponteiro para um array de int no qual ira ser montada a Heap. *@param tamanho = inteiro contendo a quantidade de elementos do array. */ void HeapSort::ordenar(int *numeros, int tamanho) { montarHeap(numeros, tamanho);// faz heap for (int i = tamanho-1; i >= 0; i--) { swapArray(numeros,0,i); ajustarHeap(numeros, 0, i); //reamontoa } }
/** * Método que reajusta uma heap que foi desarrumada. * *@param *numeros = ponteiro para um array de int no qual ira ser montada a Heap. *@param i = index do elemento a ser usado como nodo pai, para ajustar a heap. *@param tamanho = inteiro contendo a quantidade de elementos do array. */ void HeapSort::ajustarHeap(int *numeros, int i, int tamanho ) { int esquerda =(2*i)+1; int direita = (2*i)+2; int maior = i; if(esquerda < tamanho && (numeros[esquerda]>numeros[maior]) ){ maior = esquerda; } if(direita < tamanho && (numeros[direita]>numeros[maior])){ maior = direita; } if(maior!= i){ swapArray(numeros,i,maior); ajustarHeap(numeros,maior,tamanho); } }
// Se tiver mais de 1 elementos: // - swap entre a raiz (que será removido por ter maior prioridade) e o último; // depois ajusta o vetor para obedecer a propriedade de ordem do Heap: // - "desce" o elemento da raiz enquanto seus filhos tiverem maior prioridade. static void* _desenfileirar(TTAD* t){ TDadoTAD *d = t->dado; int posUltimo = d->ocupacao - 1; void *raiz = NULL; TArrayDinamico *vet = d->vetorFila; if(posUltimo >= 0){ raiz = vet->acessar(vet, 0); vet->atualizar(vet, 0, vet->acessar(vet, posUltimo)); vet->atualizar(vet, posUltimo, raiz); t->movimentacoes_desenfileirar++; d->ocupacao--; posUltimo = d->ocupacao - 1; // posUltimo = (--d->ocupacao) - 1; if(posUltimo > 0) ajustarHeap(t, 0, posUltimo); } return raiz; }