1. 程式人生 > >用java簡單實現散列表

用java簡單實現散列表

一個好的散列表設計,除了要選擇一個性能比較好的雜湊函式,還需要一個好的解決衝突的方式。這裡我們選擇除留取餘法作為雜湊函式,選擇鏈地址法作為衝突處理方式。
儲存結構如下實現程式碼
import java.util.ArrayList;

public class MyhashTable {
	
	//最開始的最大容量
	private static final int MAX_SIZE=21;
	/*
	 * 擴容因子
	 * 當達到最大容量*0.75時擴容一倍
	 */
	private static final float LOAD_FACTOR=0.75f;
	
	/*
	 * 連結串列節點
	 */
	class Entry{
		private int key;
		private int value;
		private Entry next;
		public Entry(int key,int value,Entry next)
		{
			super();
			this.key=key;
			this.value=value;
			this.next=next;
		}
	}
	private Entry table[]=new Entry[MAX_SIZE];
	private long szie=0;
	private long use=0;
	private ArrayList<Integer> keyset=new ArrayList<Integer>();
	/*
	 * 通過除留取餘法計算key在表中的hash位置
	 */
	private int hash(int key)
	{
		return key%this.table.length;
	}
	/*
	 * 將資料以key,value方式插入
	 */
	public void put(int key,int value)
	{
		int index=hash(key);
		//首先判斷陣列在index位置是否已有資料
		if(table[index]==null)
		{
			table[index]=new Entry(-1, -1, null);
		}
		Entry e=table[index];
		if(e.next==null)
		{
			table[index].next=new Entry(key, value, null);
			szie++;
			use++;
			addKey(key);
			//擴容
			if(use>=table.length*LOAD_FACTOR)
			{
				resize();
			}
		}
		else{
			for(e=e.next;e!=null;e=e.next)
			{
				int k=e.key;
				if(k==key){//如果已經有該key則改變value值
					e.value=value;
					return;
				}
			}
			
			Entry temp=table[index].next;
			Entry newEntry=new Entry(key, value, temp);//頭插法
			table[index].next=newEntry;
			szie++;
			addKey(key);
		}
	}
	/*
	 * 刪除
	 */
	public void  remove(int key) {
		int index=hash(key);
		Entry e=table[index];
		Entry pre=table[index];
		if(e!=null&& e.next!=null)
		{
			for (e = e.next;  e!=null; pre=e,e=e.next) {
				int k=e.key;
				if (k==key) {
					removeSetKey(key);
					pre.next=e.next;
					szie--;
					return;
				}
			}
		}
	}
	/*
	 * 通過key獲取value
	 * 
	 */
	public int get(int key)
	{
		int index=hash(key);
		Entry e=table[index];
		if(e!=null&&e.next!=null){
			for ( e = e.next; e!=null; e=e.next) {
				int k=e.key;
				if(key==k)
				{
					return e.value;
				}
			}
		}
		return -1;
	}
	/*
	 * 獲取元素個數
	 */
	public long size(){
		return this.szie;
	}
	/*擴容 */
	private void resize(){
		int newlength=table.length*2;
		Entry[] oldTable=table;
		table=new Entry[newlength];
		use=0;
		for(int i=0;i<oldTable.length;i++)
		{
			if(oldTable[i]!=null&& oldTable[i].next!=null)
			{
				Entry e=oldTable[i];
				while(null!=e.next){
					Entry next=e.next;
					int index=hash(next.key);
					if(table[index]==null){
						use++;
						table[index]=new Entry(-1, -1, null);
					}
					Entry temp=table[index].next;
					Entry newEntry=new Entry(next.key, next.value, temp);//頭插法
					table[index].next=newEntry;
					e=next;
				}
			}
		}
	}
	public ArrayList<Integer> Keyset() {
		return keyset;
	}
	
	private void addKey(Integer key) {
		
		this.keyset.add(key);
	}
	private void removeSetKey(Integer key) {
		
		this.keyset.remove(key);
	}
	public  static void main(String []args)
	{
		MyhashTable test=new MyhashTable();
		test.put(1, 2);
		test.put(3, 5);
		test.put(2, 5);
		test.put(9, 3);
		
		for(int x:test.Keyset())
		{
			System.out.println(x);
		}
		System.out.println("===============================");
		test.remove(3);
		for(int x:test.Keyset())
		{
			System.out.println(x);
		}
	}
	
}