Java中的Hash结构有HashSet,HashTable和HashMap,哈希表中的每个位置称为桶(bucket),当发生哈希冲突时就以链表形式存放多个元素。
关键字值key和储存位置的对应关系h,这种对应关系我们称之为Hash函数,h(key)就是Hash地址。按这种思想建立的查找表就是Hash表。这样查询速度必须快。但是一般情况下不存在理想的一对一关系,关键字通常也不是数值类型,而是字符型或其他数据类型。
在构造Hash函数之前,我们需要知道:
1.Hash函数本质上是集合到集合的映像,一个数学函数很难完成反应这种对应关系。
2.Hash要尽量减少冲突。
Hash函数的构造方法:
1.直接定值法,现行函数直接定值:
h(key) = key 或者 h(key) = a*key + b
2.字符串数值散列法:
Eg: public int hash1(String s,int n){
int i,sum;
i=0;
int[] x= stringToInts(s);
while(i<10 ){
sum=sum+x[i++];
sum=sum%n;
}
public static int[] stringToInts(String s){
int[] n = new int[s.length()];
for(int i = 0;i<s.length();i++){
n[i] = Integer.parseInt(s.substring(i,i+1));
}
return n;
}
其他函数如:UNIX系统V4版本中可执行文件与目标文件中的ELFHash函数(Exextable and Linking Format)。*自行百度*
3.平方取中法
现将关键字平方然后去其而兼职表达式中的r位作为函数值
4.取值散列法
最简单了,h(key) = key mod p
5.随机数法
适用于关键字长度不等的Hash函数构造
h(key) = random(key)
处理冲突的方法:
1.开放定位法
再次确定Hash地址:
h1 = (h(key)+d)mod n
2.Rehash法
现在写一个简单的旋转Hash函数并与系统的HashSet函数进行比较:
package Hash; import java.util.HashSet; public class Test { //存储数据链表的数组 private node[] array; public Test(int length){ array = new node[length]; } //对数据进行Hash计算 //旋转hash public static int hash(Object value){ int hash, i; String s; s=value.toString(); for (hash=s.length(), i=0; i<s.length(); ++i) hash = (hash<<4)^(hash>>28)^s.charAt(i); return (hash ^ (hash>>10) ^ (hash>>20)); } //根据Hash码得到其索引位置 private int indexFor(int hashCode){ return hashCode & (array.length-1); } /** * 添加数据 */ public void add(Object value) { //根据value得到index int index = indexFor(hash(value)); //由value创建一个新节点newNode node newNode = new node(value); //由index得到一个节点node node node = array[index]; //判断由index得到的节点是否为空,若空则将新节点放入其中,若不为空则遍历这个点上的链表 if (node == null) { array[index]=newNode; } else { node nextNode; //判断下一个节点是否或者该节点等于新节点的值 while (!node.getValue().equals(value) && (nextNode = node.getNext())!=null) { node = nextNode; } //若值不相等则加入新节点 if (!node.getValue().equals(value)) { node.setNext(newNode); } } } /** * 移除数据 * @return 移除是否成功 */ public boolean remove(Object value) { int index = indexFor(hash(value)); node node = array[index]; //若对应的第一个节点就是要remove的值 if (node!=null && node.getValue().equals(value)) { array[index]=node.getNext(); return true; } node lastNode = null; //若不是第一个节点就通过链表继续查找 while (node!=null && !node.getValue().equals(value)) { lastNode = node;//记录上一个节点 node = node.getNext(); } if (node!=null && node.getValue().equals(value)) { lastNode.setNext(node.getNext()); return true; }else { return false; } } //测试 public static void main(String[] args) { Test test = new Test(100); Long abegin=System.currentTimeMillis(); for(int i=0;i<10000;i++){ test.add(""+i); } Long aend=System.currentTimeMillis(); System.out.println("旋转哈希插入数据时间"+(aend-abegin)); Long bbegin=System.currentTimeMillis(); test.remove(""+10000); Long bend=System.currentTimeMillis(); System.out.println("旋转哈希移除时间:"+(bend-bbegin)); HashSet<String> test2 = new HashSet<String>(); Long begin=System.currentTimeMillis(); for(int i=0;i<10000;i++){ test2.add(""+i); } Long end=System.currentTimeMillis(); System.out.println("系统HashSet插入时间:"+(end-begin)); Long rBeginTime2=System.currentTimeMillis(); test2.remove(""+10000); Long rEndTime2=System.currentTimeMillis(); System.out.println("系统HashSet移除时间:"+(rEndTime2-rBeginTime2)); } }
package Hash; public class node { private Object value; private node next; public node(){ } public node(Object value ){ this.value = value; } public Object getValue() { return value; } public void setValue(Object value) { this.value = value; } public node getNext() { return next; } public void setNext(node next) { this.next = next; } }
旋转哈希插入数据时间189
旋转哈希移除时间:0
系统HashSet插入时间:37
系统HashSet移除时间:0
代码参考自 http://931646813.iteye.com/blog/1967976
没有写rehash的方法,下次补上
<!--EndFragment--><!--EndFragment-->
相关推荐
Java数据结构 线性表,链表,哈希表是常用的数据结构,在进行Java开发时,JDK已经为我们提供了一系列相应的类来实现基本的数据结构
数据结构(Java语言描述) 单元设计_单元8 哈希表.doc 学习资料 复习资料 教学资源
java 实现常用数据结构(链表,集合,栈,哈希表,搜索,排序等).
数据结构学习笔记(5)——使用draw.io绘制的映射、哈希表和跳跃表图,详细绘制了映射、哈希表和跳跃表图,使用draw.io——免费开源的画图工具。
讲解哈希函数,哈希表的原理以及常用运算。 是常用的数据结构
主要介绍了哈希表HashMap的深入学习,哈希表是一种非常重要的数据结构,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表,本文会对java集合框架中HashMap的实现原理进行讲解。感兴趣的话可以...
public class HashTabDemo { public static void main(String[] args) { HashTab hashTab = new HashTab(7); String key = ""; Scanner scanner = new Scanner(System.in); while (true){ ...
哈希表经典讲解+各项优化+分析哈希表经典讲解+各项优化+分析哈希表经典讲解+各项优化+分析哈希表经典讲解+各项优化+分析哈希表经典讲解+各项优化+分析哈希表经典讲解+各项优化+分析哈希表经典讲解+各项优化+分析哈希...
c语言数据结构 源代码 简单的操作
java java_leetcode面试题解哈希表第170题数据结构设计_题解
哈希表的设计与实现。 有文档、源代码,数据结构的课程设计
哈希表是构造出来的一种可以快速查找的存储结构。 哈希存储的基本思想是以关键字为自变量,通过一定的函数关系(称为散列函数或者哈希函数),计算出对应的函数值,以这个值作为数据元素的地址,将该数据元素存到...
哈希表冲突可视化 该项目是作为 2013 年秋季数据结构课程的项目创建的。该项目使用线性探测来处理冲突,将随机数的插入和冲突可视化到哈希表中。 您可以在下载与此项目关联的 JAR 文件,也可以自己编译该项目。 该...
在本篇文章里小编给大家分享了关于java数据结构和算法中哈希表的相关知识点内容,需要的朋友们学习下。
哈希表是一种使用哈希函数组织数据,以支持快速插入和搜索的数据结构。 有两种不同类型的哈希表:哈希集合(理解为set)和哈希映射(理解为dictionary)。 哈希集合是集合数据结构的实现之一,用于存储非重复值。 哈希...
对于两个 Java 语言的源程序代码,用哈希表的方法分别统计两个程序中使用 Java 语言关键字的情况,并最终按定量的计算结果, 得出两份程序的相似性。
全书共分为15章,分别讲述了基本概念、数组、简单排序、堆和队列、链表、递归、进阶排序、二叉树、红黑树、哈希表及图形等知识。附录中则提供了运行专题Applet和例程、相关书籍和问题解答。《Java数据结构和算法》...
java 算法:包括数组,哈希表,队列,栈,链表(双端,单向,双向),二叉树(普通二叉树,哈夫曼树,二叉查找树,平衡二叉树,二叉线索树),图这些数据结构的实现以及多种排序算法和其他一些算法的实现(递归,二...
面试中,经常要用到的数据结构(链表、队列、栈、二叉树、哈希表等)以及一些常用的算法(排序:归并、快速排序、基数排序等,查找:二分查找法),,统一由JAVA实现..zip
全书共分为15章,分别讲述了基本概念、数组、简单排序、堆和队列、链表、递归、进阶排序、二叉树、红黑树、哈希表及图形等知识。附录中则提供了运行专题Applet和例程、相关书籍和问题解答。本书提供了学完一门编程...