Advertisement
Manioc

heappy

Jun 30th, 2018
188
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5.39 KB | None | 0 0
  1. package adt.heap;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.Arrays;
  5. import java.util.Comparator;
  6.  
  7. import util.Util;
  8.  
  9. /**
  10.  * O comportamento de qualquer heap é definido pelo heapify. Neste caso o
  11.  * heapify dessa heap deve comparar os elementos e colocar o maior sempre no
  12.  * topo. Ou seja, admitindo um comparador normal (responde corretamente 3 > 2),
  13.  * essa heap deixa os elementos maiores no topo. Essa comparação não é feita
  14.  * diretamente com os elementos armazenados, mas sim usando um comparator.
  15.  * Dessa forma, dependendo do comparator, a heap pode funcionar como uma max-heap
  16.  * ou min-heap.
  17.  */
  18. public class HeapImpl<T extends Comparable<T>> implements Heap<T> {
  19.  
  20.    protected T[] heap;
  21.    protected int index = -1;
  22.    /**
  23.     * O comparador é utilizado para fazer as comparações da heap. O ideal é
  24.     * mudar apenas o comparator e mandar reordenar a heap usando esse
  25.     * comparator. Assim os metodos da heap não precisam saber se vai funcionar
  26.     * como max-heap ou min-heap.
  27.     */
  28.    protected Comparator<T> comparator;
  29.  
  30.    private static final int INITIAL_SIZE = 20;
  31.    private static final int INCREASING_FACTOR = 10;
  32.  
  33.    /**
  34.     * Construtor da classe. Note que de inicio a heap funciona como uma
  35.     * min-heap.
  36.     */
  37.    @SuppressWarnings("unchecked")
  38.    public HeapImpl(Comparator<T> comparator) {
  39.       this.heap = (T[]) (new Comparable[INITIAL_SIZE]);
  40.       this.comparator = comparator;
  41.    }
  42.  
  43.    // /////////////////// METODOS IMPLEMENTADOS
  44.    private int parent(int i) {
  45.       return (i - 1) / 2;
  46.    }
  47.  
  48.    /**
  49.     * Deve retornar o indice que representa o filho a esquerda do elemento
  50.     * indexado pela posicao i no vetor
  51.     */
  52.    private int left(int i) {
  53.       return (i * 2 + 1);
  54.    }
  55.  
  56.    /**
  57.     * Deve retornar o indice que representa o filho a direita do elemento
  58.     * indexado pela posicao i no vetor
  59.     */
  60.    private int right(int i) {
  61.       return (i * 2 + 1) + 1;
  62.    }
  63.  
  64.    @Override
  65.    public boolean isEmpty() {
  66.       return (index == -1);
  67.    }
  68.  
  69.    @Override
  70.    public T[] toArray() {
  71.       ArrayList<T> resp = new ArrayList<T>();
  72.       for (T elem : this.heap) {
  73.           if(elem != null)
  74.               resp.add(elem);
  75.       }
  76.       return (T[]) resp.toArray(new Comparable[0]);
  77.    }
  78.  
  79.    // ///////////// METODOS A IMPLEMENTAR
  80.    /**
  81.     * Valida o invariante de uma heap a partir de determinada posicao, que pode
  82.     * ser a raiz da heap ou de uma sub-heap. O heapify deve colocar os maiores
  83.     * (comparados usando o comparator) elementos na parte de cima da heap.
  84.     */
  85.    private void heapify(int position) {
  86.       if(this.heap[position] != null) {
  87.           int left = this.left(position);
  88.           int right = this.right(position);
  89.           if(this.heap[left] != null && (this.heap[right] == null || this.comparator.compare(this.heap[left], this.heap[right]) > 0)) {
  90.               if(this.comparator.compare(this.heap[left], this.heap[position]) > 0) {
  91.                   Util.swap(heap, left, position);
  92.                   this.heapify(left);
  93.               }
  94.           }else if(this.heap[right] != null) {
  95.               if(this.comparator.compare(this.heap[right], this.heap[position]) > 0) {
  96.                   Util.swap(heap, right, position);
  97.                   this.heapify(right);
  98.               }
  99.           }
  100.       }
  101.    }
  102.  
  103.    @Override
  104.    public void insert(T element) {
  105.       // ESSE CODIGO E PARA A HEAP CRESCER SE FOR PRECISO. NAO MODIFIQUE
  106.       if (index == heap.length - 1) {
  107.          heap = Arrays.copyOf(heap, heap.length + INCREASING_FACTOR);
  108.       }
  109.      
  110.       if(element != null) {
  111.           this.heap[++this.index] = element;
  112.          
  113.           int atual = this.index;
  114.           while(atual > 0 && this.comparator.compare(this.heap[atual], this.heap[this.parent(atual)]) > 0) {
  115.              
  116.               Util.swap(heap, atual, this.parent(atual));
  117.               atual = this.parent(atual);
  118.           }
  119.       }
  120.      
  121.    }
  122.  
  123.    @Override
  124.    public void buildHeap(T[] array) {
  125.      
  126.       for(int i = 0; i < array.length; i++) {
  127.           if(array[i] != null) {
  128.               this.heap[i] = array[i];
  129.           }
  130.           index++;
  131.       }
  132.       int idx = this.parent(this.index);
  133.       while(idx >= 0) {
  134.           this.heapify(idx--);
  135.       }
  136.    }
  137.  
  138.    @Override
  139.    public T extractRootElement() {
  140.        T ans = null;
  141.        if(index != -1) {
  142.            ans = this.heap[0];
  143.            Util.swap(this.heap, 0, index);
  144.            this.heap[index--] = null;
  145.            this.heapify(0);
  146.        }
  147.      
  148.        return ans;
  149.    }
  150.  
  151.    @Override
  152.    public T rootElement() {
  153.       return this.heap[0];
  154.    }
  155.  
  156.    @Override
  157.    public T[] heapsort(T[] array) {
  158.       Comparator<T> before = this.comparator;
  159.      
  160.       this.setComparator(new Comparator<T>() {
  161.           @Override
  162.         public int compare(T o1, T o2) {
  163.             return o1.compareTo(o2);
  164.         }
  165.       });
  166.      
  167.       buildHeap(array);
  168.       T[] arr = (T[]) new Comparable[this.size()];
  169.      
  170.       for(int i = this.index; i >= 0; i--) {
  171.           arr[i] = this.extractRootElement();
  172.       }
  173.      
  174.       this.setComparator(before);
  175.       return arr;
  176.    }
  177.    
  178.    @Override
  179.    public int size() {
  180.       return index+1;
  181.    }
  182.  
  183.    public Comparator<T> getComparator() {
  184.       return comparator;
  185.    }
  186.  
  187.    public void setComparator(Comparator<T> comparator) {
  188.       this.comparator = comparator;
  189.    }
  190.  
  191.    public T[] getHeap() {
  192.       return heap;
  193.    }
  194.  
  195. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement