`

JAVA中的哈希表结构

阅读更多

      Java中的Hash结构有HashSetHashTable和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-->
0
0
分享到:
评论

相关推荐

    Java数据结构 线性表,链表,哈希表是常用的数据结构

    Java数据结构 线性表,链表,哈希表是常用的数据结构,在进行Java开发时,JDK已经为我们提供了一系列相应的类来实现基本的数据结构

    哈希表java代码

    哈希表是一种在数据结构中实现快速查找的高效方法,其核心思想是通过散列函数将数据映射到一个固定大小的数组中。在Java中,我们通常使用`HashMap`类来实现哈希表,但这里提到的是自定义实现哈希表的Java代码。这个...

    Java哈希表性能优化

    ### Java哈希表性能优化 #### 一、引言 随着现代软件开发中对高性能数据结构的需求日益增加,Java作为一种广泛应用的编程语言,其内置的数据结构优化变得尤为重要。Java的`java.util`包中提供了多种数据结构,其中...

    Java的哈希表数据结构.docx

    哈希表是一种高效的数据结构,它通过散列函数将键(key)映射到一个固定大小的数组(也称为散列表)中。在Java中,常见的哈希表实现是`java.util.HashMap`类。在提供的代码示例中,作者自定义了一个简单的哈希表`...

    哈希表的原理 数据结构

    在 Java 中,哈希表可以用来实现各种数据结构,如 HashSet、HashMap 等。这些数据结构都使用哈希表来存储和查询数据,从而提高了系统的性能。 哈希表是一种非常有用的数据结构,它的优点是查找速度快、时间算法...

    Java_Datastructure.rar_java 哈希_java 哈希表

    在IT领域,尤其是编程中,数据结构是至关重要的概念,它们是存储和组织数据...这个压缩包中的"JAVA 重写数据结构"文件可能包含对这些概念的实例化和实现,通过阅读和实践这些代码,可以深入理解哈希表在Java中的应用。

    数据结构中哈希表的实现代码

    哈希表,也被称为散列表,是数据结构中一种高效的数据存储方式,它通过特定的哈希函数将关键字(key)映射到一个固定大小的数组中,从而实现了快速的查找、插入和删除操作。在计算机科学中,哈希表是解决“查找问题...

    哈希表-浙大数据结构课件

    4. 常见的哈希表实现:在实际编程中,C++中的`std::unordered_map`、Java中的`HashMap`以及Python的`dict`都是基于哈希表实现的高效容器。这些数据结构提供了高效的插入、删除和查找操作,广泛应用于软件开发的各个...

    数据结构 哈希表 哈希算法

    哈希表,也被称为散列表,是数据结构中一种高效的数据存储和检索工具。它通过哈希函数将数据的关键字映射到一个固定大小的数组中,使得在平均情况下,查找、插入和删除操作的时间复杂度可以达到O(1)。这种高效的性能...

    数据结构-Java实现一个简单的哈希表结构SingleHashMap

    数据结构-Java实现一个简单的哈希表结构SingleHashMap,对了解哈希表的原理比较有帮助。

    数据结构(Java语言描述) 单元设计_单元8 哈希表.doc

    数据结构(Java语言描述) 单元设计_单元8 哈希表.doc 学习资料 复习资料 教学资源

    哈希表相关操作实现

    哈希表,也被称为散列表,是计算机科学中一种非常重要的数据结构,它提供了...无论是编程语言的内置数据结构,如Python的dict或Java的HashMap,还是在数据库系统、缓存机制等应用场景中,哈希表都是不可或缺的一部分。

    拉链法哈希表的设计与实现

    拉链法哈希表是一种常见的数据结构,广泛应用于各种编程语言,包括Java。在这个场景中,我们看到一个基于Java的课程设计项目,它利用拉链法实现了一个哈希表,用于电话查询系统的功能。让我们深入了解一下这个主题。...

    Java中的哈希表

    ### Java中的哈希表:深度解析与应用 #### 关于哈希:压缩映射与高效检索 哈希,又称散列,是一种将任意长度的输入转换为固定长度输出的算法,这一过程通常被称为`hashcode = hash(key)`。在Java中,哈希表通过...

    哈希表-使用Java开发的哈希表-HashTable.zip

    哈希表是一种高效的数据结构,它通过特定的算法(哈希函数)将数据映射到一个固定大小的数组中,从而实现快速的插入、查找和删除操作。在Java中,`HashTable`是早期版本(Java 1.0)提供的一种线程安全的哈希表实现...

    java-leetcode面试题解哈希表第170题数据结构设计-题解.zip

    哈希表作为数据结构中的重要一员,它的高效查找、插入和删除操作使其在实际编程问题中广泛应用。本题解将围绕LeetCode面试题中的第170题展开,通过Java实现来探讨哈希表在解决实际问题中的策略。 哈希表是一种以...

    JAVA哈希表.pdf

    Java哈希表,也称为散列表,是一种高效的数据结构,用于存储键值对。它通过哈希函数将键转换为数组的索引,从而能够快速访问数据,平均时间复杂度为O(1)。在Java中,`java.util.Hashtable`类是实现哈希表的一种方式...

    哈希表的设计与实现.rar

    哈希表是一种高效的数据结构,它通过特定的函数——哈希函数,将任意大小的键(key)映射到一个固定大小的数组中,从而实现快速的查找、插入和删除操作。这种数据结构广泛应用于软件工程、数据库系统、缓存等场景。...

    映射、哈希表和跳跃表.drawio

    数据结构学习笔记(5)——使用draw.io绘制的映射、哈希表和跳跃表图,详细绘制了映射、哈希表和跳跃表图,使用draw.io——免费开源的画图工具。

    哈希表java实现及简单演示

    总结来说,这个Java哈希表演示程序会向我们展示如何在实际应用中使用哈希表,包括哈希函数的使用、冲突的处理(可能采用链地址法)、以及可能结合`Swing`创建的GUI界面来直观呈现操作。同时,它也可能涉及到了`...

Global site tag (gtag.js) - Google Analytics