package Hash;
import java.util.ConcurrentModificationException;
import java.util.NoSuchElementException;
import 算法.Collection;
import 算法.Iterator;
/*散列表
* 使用拉链法实现
*/
public class Hash<T> implements Collection<T> {
private Entry[] table; //散列表数组
private int hashTableSize; //散列表的大小
private final double MAX_LOAD_FACTOR = 0.75; //再散列边界的百分比
private int tableThreshold; //在散列的值
private int modCount; //增删改操作加一
public Hash(){
table = new Entry[17];
hashTableSize = 0;
tableThreshold = (int)(table.length*MAX_LOAD_FACTOR);
}
//向散列表中添加值
public boolean add(T item){
int hashValue = item.hashCode()&Integer.MAX_VALUE;
int index = hashValue % table.length;
Entry<T> entry;
entry = table[index];
//判断节点是否已存在,并查找最后一个节点
while(entry != null){
//已经存在
if(entry.value.equals(item)){
return false;
}//end if
entry = entry.next;
}//end while
modCount++;
//新的元素作为头节点
entry = new Entry<T>(item, hashValue, (Entry)table[index]);
table[index] = entry;
hashTableSize ++;
//当当前表的数据大于表容量的75%时,再散列
if(hashTableSize >= tableThreshold){
rehash(hashTableSize * 2 + 1);
}
return true;
}//end add
private void rehash(int newTableSize){
Entry[] newTbale = new Entry[newTableSize],
oldTable = table;
Entry<T> entry,nextEntry;
int index;
for(int i = 0; i < table.length; i++){
entry = table[i];
if(entry != null){
do{
nextEntry = entry.next;
index = entry.hashValue % newTableSize;
//插入第一个位置
entry.next = newTbale[index];
newTbale[index] = entry;
entry = nextEntry;
}while(entry != null);
}//end if
table = newTbale;
tableThreshold =(int)(table.length * MAX_LOAD_FACTOR);
oldTable = null;
}//end for
}//end rehash
//删除节点
public boolean remove(Object item){
int index = (item.hashCode()&Integer.MAX_VALUE) % table.length;
Entry<T> curr,prev;
curr = table[index];
prev = null;
while(curr != null){
if(curr.value.equals(item)){
modCount++;
//要删除的是第一个元素
if(prev != null){
prev.next = curr.next;
}
else{
table[index] = curr.next;
}
hashTableSize --;
return true;
}//end if
else{
prev =curr;
curr = curr.next;
}
}//end while
return false;
}//end remove()
//迭代器实现
private class IteratorImpl implements Iterator<T>{
Entry<T> next; //写一个要遍历的节点
int index; //索引
int expctedModCount; //保持单操作
T lastReturend; //返回值
public IteratorImpl() {
int i = 0;
Entry<T> n = null;
expctedModCount = modCount;
if(hashTableSize != 0){
while(i < table.length && ((n = table[i]) == null)){
i++;
}
next = n;
index = i;
lastReturend = null;
}//end if
}
public boolean hasNext() {
return next != null;
}
public T next() {
if(modCount != expctedModCount){
throw new ConcurrentModificationException();
}
Entry<T> entry = next;
if(entry == null){
throw new NoSuchElementException();
}
lastReturend = entry.value;
Entry<T> n = entry.next;
int i = index;
if(n == null){
i++;
while(i < table.length && (n = table[i] )== null){
i++;
}
}
index = i;
next = n;
return lastReturend;
}//end next()
public void remove() {
if(lastReturend == null){
throw new IllegalStateException();
}
if(modCount != expctedModCount){
throw new ConcurrentModificationException();
}
Hash.this.remove(lastReturend);
expctedModCount = modCount;
lastReturend = null;
}
}
//散列表的内部节点
private static class Entry<T>{
T value; //值
int hashValue; //hash值
Entry<T> next; //下一个节点
Entry(T value, int hashValue , Entry<T> next){
this.value = value;
this.hashValue = hashValue;
this.next = next;
}
}
public void clear() {
// make all hash table entries null
for (int i=0;i < table.length;i++)
table[i] = null;
// we have modified the hash table, and it has
// no entries
modCount++;
hashTableSize = 0;
}
public boolean contains(Object item) {
// compute the hash table index
int index = (item.hashCode() & Integer.MAX_VALUE) % table.length;
Entry entry;
// entry references the front of a linked list of colliding
// values
entry = table[index];
// scan the linked list and return true if item is in list
while (entry != null)
{
if (entry.value.equals(item))
return true;
entry = entry.next;
}
return false;
}
public boolean isEmpty() {
return hashTableSize == 0 ;
}
@Override
public Iterator<T> iterator() {
return new IteratorImpl();
}
public int size() {
return hashTableSize;
}
public Object[] toArray() {
// allocate the array an an iterator
Object[] arr = new Object[hashTableSize];
Iterator<T> iter = iterator();
int i = 0;
// iterate the hash table and assign its
// values into the array
while (iter.hasNext())
{
arr[i] = iter.next();
i++;
}
return arr;
}
//toString
public String toString(){
int max = hashTableSize - 1;
StringBuffer buf = new StringBuffer();
Iterator<T> iter = iterator();
buf.append("[");
for (int i = 0; i <= max; i++)
{
buf.append(iter.next());
if (i < max)
buf.append(", ");
}
buf.append("]");
return buf.toString();
}
}