【算法】散列表及散列函数的java简单实现

【前言】

想必大家对散列表及散列函数有所了解了。

当然,散列表有两个重点问题:1、如何将一个数字映射到数组下标;

2、如何处理冲突问题?

 

ok,鉴于这是演示简单的哈希表,散列函数这样定义:

index=key%16;

而冲突的处理如何:

当映射到的位置一样,就将相关数据压入同一位置的链表。

 

【补充】遗憾的是没有在大数据下面测算效率。

 

核心代码如下:

 

package MyHashTable;

public class hashEntry {
	public Integer key=null;
	public int value=0;
	
	public hashEntry next=null;
	public hashEntry pre=null;
	

}


 

 

package MyHashTable;

import java.util.ArrayList;
import java.util.HashMap;

/**
 * 这是一个自制的哈希表,里面的散列函数采用的是:
 * 斐波那契(Fibonacci)散列法

平方散列法的缺点是显而易见的,所以我们能不能找出一个理想的乘数,而不是拿value本身当作乘数呢?答案是肯定的。

1,对于16位整数而言,这个乘数是40503 
2,对于32位整数而言,这个乘数是2654435769 
3,对于64位整数而言,这个乘数是11400714819323198485
==》例如:对于一个容量为16的哈希表,那么公式为:
    对我们常见的32位整数而言,公式: 
            index = (value * 2654435769) >> (32-4)
            4为log2 16.
            请哈希表的容量请使用2n次方根。 
            这里还有一个问题没有解决,就是假如key是字符串,那么如何映射?
            还有就是哈希表的扩容问题。
 * */
public class myhashtable {
private int size=16;
private ArrayList<hashEntry> _container=new ArrayList<hashEntry>(size);
public myhashtable(){
	for(int i=0;i<size;i++){
		_container.add(i, null);
	}
}
public ArrayList<hashEntry> getContainer(){
	return _container;
}
private int getIndex(int key){
	//return (key * 40503) >>(32-4);
	return key%16;
	
}


public boolean insert(Integer key,int value){
	if(get(key)!=null){
		return false;
	}
	int theLocIndex=getIndex(key);
	if(theLocIndex>=16){
		return false;
	}
	if(_container.get(theLocIndex)==null){
		hashEntry curEntry=new hashEntry();
		curEntry.key=key;
		curEntry.value=value;
		_container.remove(theLocIndex);
		_container.add(theLocIndex,curEntry);
		return true;
		
	}
	else if(_container.get(theLocIndex)!=null){
		hashEntry cEntry=_container.get(theLocIndex);
		hashEntry preEntry1=cEntry;
		while(cEntry!=null){
			preEntry1=cEntry;
			cEntry=cEntry.next;
		}
		hashEntry newEntry=new hashEntry();
		newEntry.pre=cEntry;
		newEntry.key=key;
		newEntry.value=value;
		preEntry1.next=newEntry;
		return true;
	}
	return false;
}

public hashEntry get(Integer key){
	int theLocIndex=getIndex(key);
	if(_container.get(theLocIndex)==null){
		return null;
	}
	else{
		hashEntry cEntry=_container.get(theLocIndex);
		while (cEntry!=null) {
			if(cEntry.key==key){
				return cEntry;
			}
			else{
				cEntry=cEntry.next;
			}
			
		}
		return null;
		
	}
}

public boolean remove(int key){
	int theLocIndex=getIndex(key);
	if(_container.get(theLocIndex)==null){
		return false;
	}
	else{
		hashEntry cEntry=_container.get(theLocIndex);
		while (cEntry!=null) {
			if(cEntry.key==key){
				if(cEntry.pre==null){
					_container.remove(theLocIndex);
					return true;
				}else{
					cEntry.pre.next=cEntry.next;
					return true;
				}
			}
			else{
				cEntry=cEntry.next;
			}
			
		}
		return false;
		
	}	
}

public boolean edit(int key,int value){
	hashEntry cEntry=get(key);
	if(cEntry==null){
		return false;
	}
	cEntry.value=value;
	return true;
}

}


 

 

ok,下面放出演示的程序:

【插入键值对:12-17】

【插入键值对:28-19】

 

【插入键值对:45-3】

 

【插入键值对:78-41】

 

【插入键值对:2-147】

 

【插入键值对:44-7】

 

删除及编辑扥都是类似的,但是哈希表不应该是这么简陋。假如大家对这个演示程序有兴趣,那么可以到下面下载:

 

 swing版简易哈希表演示工具

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值