Linha | Codigo |
001 | // Prof. Leo^nidas - http://www.matematica.br http://line.ime.usp.br |
002 | // MAC0122 - 2017/08/23 |
003 | |
004 | // Biblioteca para: ordenar vetor de inteiros via metodo da Propriedade de Monte. Complexidade: O(n log n) |
005 | // Exemplo de metodo no paradgma "DIVISAO e CONQUISTA" |
006 | // Invocar: #include "ordena_monte.h" |
007 | // ... |
008 | // XbibliotecaLOBx__ordenaMonte(int V[], int n); |
009 | |
010 | // Ordena vetor de inteiros via metodo da Ordenacao por Propriedade de Monte. Complexidade: O(n log) |
011 | // Propriedade de Monte ("Heap Sort"): |
012 | // para cada no de uma arvore, a informacao nele e' maior ou igual a de seus filhos |
013 | // info(no) >= max{ info(no.esq), info(no.dir) } |
014 | // Usa um vetor para a arvore: para um no na posicao i do vetor, seus filhos estao nas posicoes V[2*i+1] e V[2*i+2] |
015 | // Observacao importante: se uma arvore e' o Monte, entao o maior elemento esta na primeira posicao, ou seja, |
016 | // V[0] >= V[i], para todo i |
017 | // Programa recursivo para ordenar uma lista de inteiros usando a ideia manter propriedade de Monte e separa o maior. |
018 | |
019 | // Macro para trocar par de valores |
020 | #define XbibliotecaLOBx__troquePar(V, IA, IB) {int aux = V[IA]; V[IA] = V[IB]; V[IB] = aux;} |
021 | |
022 | // Supondo que V[] tem a propriedade de Monte exceto talvez em V[k] |
023 | // Entao "desca" o V[k] trocando-o com o maior filho ate' que fique maior que os 2 filhos |
024 | // Neste momento a propriedade de Monte estara restaurada |
025 | void XbibliotecaLOBx__desceElementoMonte (int V[], int k, int N) { |
026 | int j; |
027 | while (2*k + 1 < N) { // tem algum filho? (V[k] -> { V[2*k, V[2*k+2] } |
028 | j = 2*k + 1; // primeiro filho de "k" |
029 | if (j < N-1 && V[j] < V[j+1]) // se tem 2 filhos e maior em j+1, aponte para j+1 |
030 | j++; |
031 | if (V[k] >= V[j]) { |
032 | break; |
033 | } |
034 | XbibliotecaLOBx__troquePar(V, k, j); // o "define" acima colocara aquele codigo aqui |
035 | k = j; // recome com o "maior filho" |
036 | } |
037 | } |
038 | |
039 | void XbibliotecaLOBx__ordenaMonte (int V[], int tam) { |
040 | int k, N = tam; |
041 | // Cria propriedade inicial de Monte |
042 | for (k = N/2-1; k >= 0; k--) // comece pelo primeiro no que tem filho |
043 | XbibliotecaLOBx__desceElementoMonte(V, k, N); // desca-o de modo sua sub-arvore ser Monte |
044 | while (N > 0) { |
045 | // Elemento no topo e' maior => passe para ultima posicao |
046 | XbibliotecaLOBx__troquePar(V, 0, N-1); |
047 | // Estragou propriedade de monte na posicao 0, desca para recuperar propriedade |
048 | XbibliotecaLOBx__desceElementoMonte(V, 0, --N); |
049 | } |
050 | } |