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, 2, (), () |] */ public String verbose() { String s="[| "; for(int i=0;i," : table[i].item+","; return s.substring(0,s.length()-1) + " |]"; } /** * Traduz a tabela numa string * @return a string que descreve a tabela, eg, [| (key1:item1), (key2:item2) |] */ public String toString() { String s="[| "; for(int i=0;i= 0) for (int i=nextElem; i " + ht.retrieve("13t")); System.out.println(cp); System.out.println(cp.equals(ht)); } } // endClass HashTable //***** Exemplo de Funçao de Dispersão class HashString implements HashFunction { private int actualValue; public HashString() { actualValue = 0; } public int hashValue(Object key) { actualValue=0; for(int i=0;i<((String)key).length();i++) actualValue += (int)((String)key).charAt(i); return actualValue; } public boolean isHashable(Object key) { return key instanceof String; } public int nextValue() { actualValue += 4; return actualValue; } }