123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- package org.insa.graphs.algorithm.utils;
-
- import java.util.ArrayList;
-
- /**
- * Implements a binary heap containing elements of type E.
- *
- * Note that all comparisons are based on the compareTo method, hence E must
- * implement Comparable
- *
- * @author Mark Allen Weiss
- * @author DLB
- */
- public class BinaryHeap<E extends Comparable<E>> implements PriorityQueue<E> {
-
- // Number of elements in heap.
- private int currentSize;
-
- // The heap array.
- protected final ArrayList<E> array;
-
- /**
- * Construct a new empty binary heap.
- */
- public BinaryHeap() {
- this.currentSize = 0;
- this.array = new ArrayList<E>();
- }
-
- /**
- * Construct a copy of the given heap.
- *
- * @param heap Binary heap to copy.
- */
- public BinaryHeap(BinaryHeap<E> heap) {
- this.currentSize = heap.currentSize;
- this.array = new ArrayList<E>(heap.array);
- }
-
- /**
- * Set an element at the given index.
- *
- * @param index Index at which the element should be set.
- * @param value Element to set.
- */
- private void arraySet(int index, E value) {
- if (index == this.array.size()) {
- this.array.add(value);
- }
- else {
- this.array.set(index, value);
- }
- }
-
- /**
- * @return Index of the parent of the given index.
- */
- protected int indexParent(int index) {
- return (index - 1) / 2;
- }
-
- /**
- * @return Index of the left child of the given index.
- */
- protected int indexLeft(int index) {
- return index * 2 + 1;
- }
-
- /**
- * Internal method to percolate up in the heap.
- *
- * @param index Index at which the percolate begins.
- */
- private void percolateUp(int index) {
- E x = this.array.get(index);
-
- for (; index > 0
- && x.compareTo(this.array.get(indexParent(index))) < 0; index = indexParent(
- index)) {
- E moving_val = this.array.get(indexParent(index));
- this.arraySet(index, moving_val);
- }
-
- this.arraySet(index, x);
- }
-
- /**
- * Internal method to percolate down in the heap.
- *
- * @param index Index at which the percolate begins.
- */
- private void percolateDown(int index) {
- int ileft = indexLeft(index);
- int iright = ileft + 1;
-
- if (ileft < this.currentSize) {
- E current = this.array.get(index);
- E left = this.array.get(ileft);
- boolean hasRight = iright < this.currentSize;
- E right = (hasRight) ? this.array.get(iright) : null;
-
- if (!hasRight || left.compareTo(right) < 0) {
- // Left is smaller
- if (left.compareTo(current) < 0) {
- this.arraySet(index, left);
- this.arraySet(ileft, current);
- this.percolateDown(ileft);
- }
- }
- else {
- // Right is smaller
- if (right.compareTo(current) < 0) {
- this.arraySet(index, right);
- this.arraySet(iright, current);
- this.percolateDown(iright);
- }
- }
- }
- }
-
- @Override
- public boolean isEmpty() {
- return this.currentSize == 0;
- }
-
- @Override
- public int size() {
- return this.currentSize;
- }
-
- @Override
- public void insert(E x) {
- int index = this.currentSize++;
- this.arraySet(index, x);
- this.percolateUp(index);
- }
-
- @Override
- public void remove(E x) throws ElementNotFoundException {
- int index;
- int indexLast;
- E lastElement;
- if (this.isEmpty())
- throw new ElementNotFoundException(x);
- else {
- index = this.array.indexOf(x);
- /* Si on n'a pas trouve l'element, on souleve une exception */
- if (index == -1 || index >= this.currentSize) {
- throw new ElementNotFoundException(x);
- }
- /* Si l'element a ete trouve, on le supprime */
- else {
- indexLast=--this.currentSize;
- /* Si l'element supprime n'etait pas le dernier */
- if (indexLast>index) {
- lastElement = this.array.get(indexLast);
- this.array.set(index, lastElement);
- this.percolateDown(index);
- this.percolateUp(index);
- }
- }
-
- }
- }
-
- @Override
- public E findMin() throws EmptyPriorityQueueException {
- if (isEmpty())
- throw new EmptyPriorityQueueException();
- return this.array.get(0);
- }
-
- @Override
- public E deleteMin() throws EmptyPriorityQueueException {
- E minItem = findMin();
- E lastItem = this.array.get(--this.currentSize);
- this.arraySet(0, lastItem);
- this.percolateDown(0);
- return minItem;
- }
- /**
- * Creates a multi-lines string representing a sorted view of this binary heap.
- *
- * @return a string containing a sorted view this binary heap.
- */
- public String toStringSorted() {
- return BinaryHeapFormatter.toStringSorted(this, -1);
- }
-
- /**
- * Creates a multi-lines string representing a sorted view of this binary heap.
- *
- * @param maxElement Maximum number of elements to display. or {@code -1} to
- * display all the elements.
- *
- * @return a string containing a sorted view this binary heap.
- */
- public String toStringSorted(int maxElement) {
- return BinaryHeapFormatter.toStringSorted(this, maxElement);
- }
-
- /**
- * Creates a multi-lines string representing a tree view of this binary heap.
- *
- * @return a string containing a tree view of this binary heap.
- */
- public String toStringTree() {
- return BinaryHeapFormatter.toStringTree(this, Integer.MAX_VALUE);
- }
-
- /**
- * Creates a multi-lines string representing a tree view of this binary heap.
- *
- * @param maxDepth Maximum depth of the tree to display.
- *
- * @return a string containing a tree view of this binary heap.
- */
- public String toStringTree(int maxDepth) {
- return BinaryHeapFormatter.toStringTree(this, maxDepth);
- }
-
- @Override
- public String toString() {
- return BinaryHeapFormatter.toStringTree(this, 8);
- }
-
- public boolean isValid() {
- boolean valide = true;
- for (int i = 0; i < this.currentSize && valide; i++) {
- if (this.indexLeft(i) <= this.currentSize) {
- if (this.array.get(this.indexLeft(i)).compareTo(this.array.get(i)) == -1) {
- valide = false;
- }
- else {
- if (this.indexLeft(i) + 1 < this.currentSize) {
- if (this.array.get(this.indexLeft(i) + 1).compareTo(this.array.get(i)) == -1) {
- valide = false;
- }
- }
- }
- }
- }
- return valide;
- }
-
- }
|