Manioc

heap

Jun 28th, 2018
280
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 4.71 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.          resp.add(elem);
  74.       }
  75.       return (T[]) resp.toArray(new Comparable[0]);
  76.    }
  77.  
  78.    // ///////////// METODOS A IMPLEMENTAR
  79.    /**
  80.     * Valida o invariante de uma heap a partir de determinada posicao, que pode
  81.     * ser a raiz da heap ou de uma sub-heap. O heapify deve colocar os maiores
  82.     * (comparados usando o comparator) elementos na parte de cima da heap.
  83.     */
  84.    private void heapify(int position) {
  85.       if(position <= index) {
  86.           int left = this.left(position);
  87.           int right = this.right(position);
  88.           if(( left <= index &&  right > index) || this.comparator.compare(this.heap[left], this.heap[right]) < 0) {
  89.               if( left <= index && this.comparator.compare(this.heap[left], this.heap[position]) < 0) {
  90.                   Util.swap(getHeap(), left, position);
  91.                   this.heapify(left);
  92.               }
  93.           }else {
  94.               if( right <= index && this.comparator.compare(this.heap[right], this.heap[position]) < 0) {
  95.                   Util.swap(getHeap(), right, position);
  96.                   this.heapify(right);
  97.               }
  98.           }
  99.       }
  100.    }
  101.  
  102.    @Override
  103.    public void insert(T element) {
  104.       // ESSE CODIGO E PARA A HEAP CRESCER SE FOR PRECISO. NAO MODIFIQUE
  105.       if (index == heap.length - 1) {
  106.          heap = Arrays.copyOf(heap, heap.length + INCREASING_FACTOR);
  107.       }
  108.      
  109.       if(element != null) {
  110.           this.heap[++this.index] = element;
  111.          
  112.           int atual = this.index;
  113.           while(atual > 0 && this.comparator.compare(this.heap[atual], this.heap[this.parent(atual)]) < 0) {
  114.               Util.swap(heap, atual, this.parent(atual));
  115.               atual = this.parent(atual);
  116.           }
  117.       }
  118.      
  119.    }
  120.  
  121.    @Override
  122.    public void buildHeap(T[] array) {
  123.      
  124.       for(int i = 0; i < array.length; i++) {
  125.           this.heap[i] = array[i];
  126.           index++;
  127.       }
  128.       int idx = this.parent(this.index);
  129.       while(this.index >= 0) {
  130.           this.heapify(idx--);
  131.       }
  132.    }
  133.  
  134.    @Override
  135.    public T extractRootElement() {
  136.        T ans = null;
  137.        if(index != -1) {
  138.            ans = this.heap[0];
  139.            Util.swap(this.heap, 0, index--);
  140.            this.heapify(0);
  141.        }
  142.        return ans;
  143.    }
  144.  
  145.    @Override
  146.    public T rootElement() {
  147.       return this.heap[0];
  148.    }
  149.  
  150.    @Override
  151.    public T[] heapsort(T[] array) {
  152.       return  null;
  153.    }
  154.  
  155.    @Override
  156.    public int size() {
  157.       return index+1;
  158.    }
  159.  
  160.    public Comparator<T> getComparator() {
  161.       return comparator;
  162.    }
  163.  
  164.    public void setComparator(Comparator<T> comparator) {
  165.       this.comparator = comparator;
  166.    }
  167.  
  168.    public T[] getHeap() {
  169.       return heap;
  170.    }
  171.  
  172. }
Advertisement
Add Comment
Please, Sign In to add comment