package dataStructures;
import java.util.*;
/**
*
Titulo: Uma implementaçao vectorial do Amontoado
* Descrição: Esta implementaçao a caracteristica de que os amontoados
* podem ser facilmente descritos em vectores, dado serem
* representados por árvores completas
* @version 1.0
*/
public class VHeap implements Heap,Cloneable {
private final int DELTA = 128;
private int nElems;
private Object[] theHeap;
public VHeap() {
theHeap = new Object[DELTA];
nElems = 0;
}
//@ requires isHeap(t);
public VHeap(BinTree t) {
this();
constr(t.root(),t.left(),t.right());
}
public BinTree empty() {
return new VHeap();
}
public void constr(Object item, BinTree left, BinTree right) {
theHeap = new Object[DELTA + left.length() + right.length()];
theHeap[0] = item;
nElems = 1;
VQueue qTrees = new VQueue();
VQueue qIndex = new VQueue();
qTrees.enqueue(left);
qIndex.enqueue(new Integer(1));
qTrees.enqueue(right);
qIndex.enqueue(new Integer(2));
while (!qTrees.isEmpty()) {
BinTree t = ((BinTree)(qTrees.front()));
int i = ((Integer)(qIndex.front())).intValue();
qTrees.dequeue();
qIndex.dequeue();
theHeap[i] = t.root();
nElems = i+1;
if (!t.left().isEmpty()) {
qTrees.enqueue(t.left());
qIndex.enqueue(new Integer(left(i)));
}
if (!t.right().isEmpty()) {
qTrees.enqueue(t.right());
qIndex.enqueue(new Integer(right(i)));
}
} //while
}
public boolean isEmpty() {
return nElems==0;
}
private int left(int index) {
return 2 * index + 1;
}
private int right(int index) {
return 2 * index + 2;
}
private int father(int index) {
return (index-1)/2;
}
private boolean isEmpty(int index) {
return index >= nElems || theHeap[index] == null;
}
private boolean isLeaf(int index) {
return isEmpty(left(index)) && isEmpty(right(index));
}
public boolean isLeaf() {
return isLeaf(0);
}
public Object root() {
return theHeap[0];
}
public BinTree left() {
int i=0;
VHeap result = new VHeap();
result.theHeap = new Object[nElems]; // ajustar dimensão
for(int start=2,size=1; start<=nElems; start*=2,size*=2)
for(int j=start-1;j=nElems)
break;
result.theHeap[i++] = theHeap[j];
}
result.nElems = i;
return result;
}
public BinTree right() {
int i=0;
VHeap result = new VHeap();
result.theHeap = new Object[nElems]; // ajustar dimensão
for(int start=2,size=1; start<=nElems; start*=2,size*=2)
for(int j=start-1+size;j=nElems)
break;
result.theHeap[i++] = theHeap[j];
}
result.nElems = i;
return result;
}
/**
* A árvore é cheia?
* @param t A árvore
* @return TRUE se 't' é cheia, FALSE c.c.
*/
private boolean isFull(BinTree t) {
return Math.pow(2,t.height())-1 == t.length();
}
/**
* A árvore é completa? ie, é equilibrada e todas as folhas
* do último nível estão preenchidas da esquerda para a direita
* @param t A árvore
* @return TRUE se 't' é completa, FALSE c.c.
*/
private boolean isComplete(BinTree t) {
if (t.isEmpty())
return true;
BinTree l = t.left(),
r = t.right();
return (l.height() == r.height() && isFull(l) && isComplete(r)) ||
(l.height() == r.height()+1 && isFull(r) && isComplete(l));
}
/**
* A subárvore dada é de prioridade?
* @param t A árvore
* @return TRUE se 't' é de prioridade, FALSE c.c.
*/
private boolean isPriority(BinTree t) {
if (t.isEmpty() || t.isLeaf())
return true;
BinTree l = t.left(),
r = t.right();
if (l.isEmpty())
return ((Comparable)t.root()).compareTo(r.root()) >= 0;
if (r.isEmpty())
return ((Comparable)t.root()).compareTo(l.root()) >= 0;
return ((Comparable)t.root()).compareTo(r.root()) >= 0 &&
((Comparable)t.root()).compareTo(l.root()) >= 0 &&
isPriority(r) && isPriority(l);
}
private int length(int index) {
if (isEmpty(index))
return 0;
return 1 + length(left(index)) + length(right(index));
}
public int length() {
return length(0);
}
private int height(int index) {
if (isEmpty(index))
return 0;
return 1 + Math.max(height(left(index)),height(right(index)));
}
public int height() {
return height(0);
}
/** Increments the structure nElems (adds 'DELTA' new slots) */
private void grow() {
Object[] newHeap = new Object[theHeap.length + DELTA];
for(int i=0;i que 'o'
while (pos!=0 && o.compareTo(theHeap[prevPos]) > 0) {
theHeap[pos] = theHeap[prevPos];
pos = prevPos;
prevPos = father(pos);
}
theHeap[pos] = o;
nElems++;
}
*/
public void insert(Comparable o) {
if (nElems==theHeap.length)
grow();
theHeap[nElems++] = o;
moveUp();
}
private void moveUp() {
int pos = nElems-1;
while (pos != 0 &&
((Comparable)theHeap[pos]).compareTo(theHeap[father(pos)]) > 0) {
swap(pos, father(pos));
pos = father(pos);
}
}
public void remRoot() {
if (nElems>1) {
theHeap[0] = theHeap[nElems-1];
moveDown();
}
theHeap[--nElems] = null;
}
private void moveDown() {
int maxChild, pos = 0;
while (pos <= father(nElems-1)) { // posição do último nó não folha
maxChild = left(pos);
if (maxChild < nElems-1)
if (((Comparable)theHeap[maxChild]).compareTo(theHeap[maxChild+1]) < 0)
maxChild++;
if (((Comparable)theHeap[pos]).compareTo(theHeap[maxChild]) > 0)
break;
swap(pos, maxChild);
pos = maxChild;
}
}
private void swap(int i, int j) {
Object tmp = theHeap[i];
theHeap[i] = theHeap[j];
theHeap[j] = tmp;
}
/*
public void remRoot() {
int nextPos,
pos = 0; // a posição actual onde vai ser posto o último elemento
int lastPos = nElems-1; // a posiçao do último elemento
nElems--;
while (pos <= (nElems+1)/2 - 1) { // posição do último nó não folha
nextPos = left(pos); // raiz da subárvore esquerda
if (nextPos < nElems)
if (((Comparable)theHeap[nextPos]).compareTo(theHeap[nextPos+1]) < 0)
nextPos++; // escolher o maior filho (neste caso, o da direita)
if (((Comparable)theHeap[lastPos]).compareTo(theHeap[nextPos]) < 0) {
theHeap[pos] = theHeap[nextPos]; // o filho passa p/o lugar do pai
pos = nextPos; // vamos repetir agora p/o filho
}
else // o filho é menor que o ultimo elemento! Saimos do ciclo
break;
} //while()
theHeap[pos] = theHeap[lastPos]; // mudar esse último elemento p/o local certo
theHeap[nElems] = null;
}
*/
////////////////////////////////////////////////////
public boolean equals(BinTree t) {
if (isEmpty())
return t.isEmpty();
if (t.isEmpty())
return false;
return t.root().equals(root()) && t.left().equals(left()) && t.right().equals(right());
}
public String toString() {
if (isEmpty())
return "[]";
String s = "[" + theHeap[0];
for (int i=1; i