package dataStructures; import java.util.*; /** *
Titulo: O tipo dos registos a guardar na Tabela
* @version 1.0 */ class HashRegister implements Cloneable { public Object item; public Object key; public HashRegister(Object o, Object k) { item = o; key = k; } public String toString() { return "(" + key + ":" + item + ")"; } public Object clone() { return new HashRegister(item,key); } } // endClass HashRegister /////////////////////////////////////////////////////// /** *Titulo: Uma implementaçao vectorial da Tabela
*Descrição: Esta implementaçao usa funções de Dispersão para acesso * extremamente rápido ao seu conteúdo -> Hash Table
* * @author João Neto * @version 1.0 */ public class HashTable implements Table,Cloneable { private final int DELTA = 1001; protected final double LOAD_FACTOR = 0.75; protected static final HashRegister availableCell = new HashRegister(null,null); private int nElems; // Quantos elementos existem na tabela private HashRegister[] table; // O vector que guarda a tabela private HashFunction h; // A função de dispersão public HashTable( HashFunction h ) { this.h = h; table = new HashRegister[DELTA]; nElems = 0; } public Table empty() { return new HashTable(h); } public boolean isEmpty() { return nElems == 0; } private boolean isCellAvailable(int n) { return table[n] == availableCell; } private boolean isCellFree(int n) { return table[n] == null; } /** * Devolve a posiçao da chave (se existir) * @param key A chava a procurar * @return A posição de uma dada chave, ou -1 se nao existir */ private int searchPos(Object key) { int pos = h.hashValue(key) % table.length; int back = pos; do { if (isCellFree(pos)) return -1; if (isCellAvailable(pos)) pos = h.nextValue() % table.length; else if (key.equals(table[pos].key)) return pos; else pos = h.nextValue() % table.length; } while (back!=pos); return -1; } public boolean contains(Object key) { return searchPos(key) >= 0; } public Object retrieve(Object key) { return table[searchPos(key)].item; } public void remove(Object key) { int n = searchPos(key); if (n!=-1) { table[n] = availableCell; nElems--; } } public void insert(Object item, Object key) { if ((double)nElems/table.length > LOAD_FACTOR) grow(); int pos = h.hashValue(key) % table.length; while(!isCellFree(pos) && !isCellAvailable(pos)) pos = h.nextValue() % table.length; table[pos] = new HashRegister(item,key); nElems++; } /////////////////////////////////////////////////////// //@requires n>1; private boolean isPrime(int n) { if (n%2 == 0) return n==2; int limit = (int)Math.round(Math.sqrt(n)); for(int i=3;i<=limit;i+=2) if (n%i == 0) return false; return true; } private int getNextPrime(int n) { while (!isPrime(n)) n++; return n; } private void grow() { HashRegister[] oldTable = table; int newSize = getNextPrime(table.length + DELTA); table = new HashRegister[newSize]; nElems = 0; for(int i=0;i