用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);
		}
	}
	
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值