`
原非珏
  • 浏览: 9800 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

Hash结构

阅读更多
数组的特点是:寻址容易,插入和删除困难;而链表的特点是:寻址困难,插入和删除容易。
而哈希表就是结合两者的数据结构。
以下的代码是个人编写的简单Hash表结构,并与系统的进行了测试和比较。
//节点数据结构
class Node{
    private Object value;//节点的值
    private Node next;//链表中指向下一结点
   
    public Node(Object value){
    	this.value = value;
    }
    public Object getValue(){
    	return value;
    }
    public Node getNext(){
    	return next;
    }
    public void setNext(Node next){
    	this.next=next;
    }
}
/**
 * Hash结构
 * @author suer
 *
 */
public class MyHashTest{ 
	private Node[] array;//存储数据链表的数组
	//创建指定长度的数组
	public MyHashTest(int length){
		array = new Node[length];
	}
	//对数据进行Hash计算
	private static int hash (Object o){   
		int h = o.hashCode();
		h ^= (h >>> 20) ^ (h >>> 12);//java.util.HashMap中用的hash算法
		return h ^ (h >>> 7) ^ (h >>> 4);
		}
	//根据Hash码得到其索引位置
	private int indexFor(int hashCode){    
	    return hashCode & (array.length-1);
	}
	/**
	 * 添加数据
	 * @param value 添加的数据值
	 */
	public void add(Object value) {
		//根据value得到index
	    int index = indexFor(hash(value));
	    System.out.println("index:" + index + " value:" + 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);
	        }
	    }
	}
	/**
	 * 移除数据
	 * @param value 要移除的数据值
	 * @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) {
		MyHashTest mht = new MyHashTest(55);
		//MyHashTest mht = new MyHashTest(100000);
        Long aBeginTime=System.currentTimeMillis();    
        for(int i=0;i<10000;i++){    
        mht.add(""+i);    
        }    
        Long aEndTime=System.currentTimeMillis();//记录EndTime    
        System.out.println("insert time:"+(aEndTime-aBeginTime));     
          
        Long rBeginTime=System.currentTimeMillis();//记录BeginTime    
        mht.remove(""+10000);    
        Long rEndTime=System.currentTimeMillis();//记录EndTime    
        System.out.println("remove time:"+(rEndTime-rBeginTime));  

      HashSet<String> mht2 = new HashSet<String>();     
      Long aBeginTime2=System.currentTimeMillis();//记录BeginTime    
      for(int i=0;i<10000;i++){    
      mht2.add(""+i);    
      }    
      Long aEndTime2=System.currentTimeMillis();//记录EndTime    
      System.out.println("insert time:"+(aEndTime2-aBeginTime2));    
        
      Long rBeginTime2=System.currentTimeMillis();//记录BeginTime    
      mht.remove(""+10000);    
      Long rEndTime2=System.currentTimeMillis();//记录EndTime    
      System.out.println("remove time:"+(rEndTime2-rBeginTime2)); 
	}
}

测试结果如下:

很显然,当添加的数据多时,系统提供的要快的多~

还试用了一下其他的hash算法,还不完全~有兴趣的可以多找些试试~
//加法hash,h%37的37为质数,可变~
//	private static int hash(String value){   
//		int h,i;
//		h=value.length();
//		for(i=0;i<value.length();i++)
//			h+=value.charAt(i);
//	    return h%37;
//	}
//旋转hash
//	public static int hash(String value){    
//	   int hash, i;    
//	   for (hash=value.length(), i=0; i<value.length(); ++i)    
//	     hash = (hash<<4)^(hash>>28)^value.charAt(i);    
//	   return (hash ^ (hash>>10) ^ (hash>>20));    
//	}   
//Bernstein's hash 
//	public static int hash(String value){    
//	   int hash = 0;    
//	   int i;    
//	   for (i=0; i<value.length(); ++i)
//		   hash = 33*hash + value.charAt(i);    
//	   return hash;  
//改进的32位FNV算法1
//	 public static int hash(String value){    
//	        final int p = 16777619;    
//	        int hash = (int)2166136261L;    
//	        for(int i=0;i<value.length();i++)    
//	            hash = (hash ^ value.charAt(i)) * p;    
//	        hash += hash << 13;    
//	        hash ^= hash >> 7;    
//	        hash += hash << 3;    
//	        hash ^= hash >> 17;    
//	        hash += hash << 5;    
//	        return hash;    
//	 }    
//RS算法hash   
//    public static int hash(String value){    
//        int b    = 378551;    
//        int a    = 63689;    
//        int hash = 0;       
//       for(int i = 0; i < value.length(); i++){    
//          hash = hash * a + value.charAt(i);    
//          a    = a * b;    
//       }    
//       return (hash & 0x7FFFFFFF);    
//    }    
//BKDR算法   
//    public static int hash(String value)  {    
//        int seed = 131; // 31 131 1313 13131 131313 etc..    
//        int hash = 0;    
//       for(int i = 0; i < value.length(); i++)    
//       {    
//          hash = (hash * seed) + value.charAt(i);    
//       }    
//    
//       return (hash & 0x7FFFFFFF);    
//    }       
// SDBM算法     
//    public static int hash(String value){    
//        int hash = 0;    
//       for(int i = 0; i < str.length(); i++){    
//          hash = value.charAt(i) + (hash << 6) + (hash << 16) - hash;    
//       }    
//       return (hash & 0x7FFFFFFF);    
//    }    
//DJB算法     
//    public static int hash(String value){    
//       int hash = 5381;    
//       for(int i = 0; i < value.length(); i++){    
//          hash = ((hash << 5) + hash) + value.charAt(i);    
//       }       
//       return (hash & 0x7FFFFFFF);    
//    }     
//DEK算法   
//    public static int hash(String value){    
//        int hash = value.length();       
//       for(int i = 0; i < value.length(); i++)    
//       {    
//          hash = ((hash << 5) ^ (hash >> 27)) ^ value.charAt(i);    
//       }       
//       return (hash & 0x7FFFFFFF);    
//   }  
  • 大小: 10.4 KB
分享到:
评论
1 楼 jiranjiran 2013-11-03  

相关推荐

    基于Hash结构的逆向最大匹配分词算法的改进_丁振国1

    本文主要探讨了基于Hash结构的逆向最大匹配分词算法的改进,旨在提高分词速度和准确性,减少歧义。 1. 分词算法概述 - 最小匹配算法:这是一种早期的分词方法,从字符串左侧开始,每次取固定长度的字段与词典对比...

    hash表实现举例 hash结构中带超时链表的实现

    1. hash key值计算,key的比较,内存分配,可以通过实现模板类重新定制 2. 实现按插入时间的先后,通过有序链表访问节点。用于按照时间先后,快速遍历(删除)超时节点。 3. hash 实现快速存取, 链表快速实现...

    yew:提供对象访问,如对 Hash 结构的接口

    Yew 允许像遍历对象树一样遍历 Hash 结构。 用法 鉴于位于config/env.yml的以下 yml 文件: orientdb : url : ' remote:localhost/db ' user : admin pass : secret testing : frameworks : minitest : true ...

    hash表C语言实现

    哈希表(Hash Table)是一种数据结构,它通过计算一个关联数组中的索引来确定一个元素的存储位置,这种计算过程通常称为哈希函数。在C语言中实现哈希表,可以提供快速的数据查找、插入和删除操作,尤其适用于大数据...

    UMAT_Hashin3D_hashin

    总之,“UMAT_Hashin3D_hashin”是一个基于Hashin破坏准则的三维复合材料损伤分析工具,其核心在于用编程方式实现材料损伤的动态模拟,以帮助工程师理解和预测复杂复合材料结构在不同工况下的行为。

    3d.zip_3维hashin准则_Hashin 3D_hashin_失效准则_层合板 hashin

    6. **计算方法**:在实际应用中,3D Hashin准则通常与有限元分析结合,通过对材料的微结构进行模拟,计算每个单元的失效状态,并确定整个结构的整体失效。 7. **应用范围**:3D Hashin准则广泛应用于航空航天、汽车...

    HASHIN.rar_ABAQUS_Hashin失效准则 abaqus_abaqus hashin_abaqus 三维Hashi

    在实际应用中,使用三维实体单元和Hashin失效准则可以对复杂结构进行详细分析,例如评估飞机机翼、复合材料部件或其他工程结构在多向应力下的稳定性。用户子程序允许用户自定义材料模型,如Hashin失效准则,以适应...

    uthash开源的hash函数实现

    UTHASH 是一个开源的 C 语言库,提供了一种简单且高效的哈希表实现,用于在 C 代码中快速查找和管理数据结构。这个库的主要功能是提供一个宏定义的集合,可以方便地将结构体转化为哈希表,进而进行添加、删除、查找...

    hashin-strain-3d_hashin_三维hashin_三维hashin失效_失效准则_3D—Hashin_

    在实际工程应用中,三维Hashin失效准则通常与有限元分析结合,对复杂结构的复合材料进行模拟。这需要将失效准则嵌入到求解器中,通过迭代求解应力和应变场,判断材料在各个位置是否达到失效状态。这种方法既考虑了...

    Redis大Key解决方案.docx

    - 如果对象每次只需要存取部分数据,同样可以将其拆分成多个键值对,或者存储为一个Hash结构,其中每个Field代表对象的一个具体属性。这样可以通过`HGET`或`HMGET`命令获取部分Value,使用`HSET`或`HMSET`更新部分...

    C开源hash代码uthash

    该套开源代码采用宏的方式实现hash函数的相关功能,支持C语言的任意数据结构最为key值,甚至可以采用多个值作为key,无论是自定义的struct还是基本数据类型,需要注意的是不同类型的key其操作接口方式略有不通。...

    RedisKing publish.zip

    RedisKing是一款专为Redis数据库设计的管理工具,它提供了便捷的操作界面,允许用户对Redis中的数据进行读写操作,尤其适用于处理hash结构和普通的key-value结构。通过使用RedisKing,用户能够更直观地管理和维护...

    hashin失效vumat,hashin失效准则介绍,Fortran

    通过阅读和理解这个文件,工程师们可以学习如何将Hashin失效准则应用到实际的工程计算中,从而更准确地模拟和预测复合材料结构的性能和寿命。 在实际应用中,Hashin失效准则与VUMAT的结合可以帮助解决许多关键问题...

    海量非结构化数据管理方案.docx

    - Redis的优化包括选择合适的数据结构(如使用Hash结构代替set或list操作)、合理设计key过期时间、配置maxmemory和maxmemory-policy、使用命令合并和管道命令减少网络开销、优化命令复杂度以及合理设置maxclients。...

    海量非结构化数据的高效管理.docx

    - Redis的优化建议包括:根据需求选择合适的数据结构,如使用Hash结构代替Set操作;合理设定key的过期时间;配置maxmemory和maxmemory-policy以避免性能下降;设计高效的命令使用,如命令合并和管道命令;并适当设置...

    HASHIN_hashin子程序_imagehashing_Fortran_ABAQUSvumat_

    标题中的"HASHIN_hashin子程序_imagehashing_Fortran_ABAQUSvumat_" 提到了几个关键概念:HASHIN子程序、imagehashing、Fortran编程语言以及ABAQUS的VUMAT(用户材料子程序)。这些元素共同构成了一个在ABAQUS环境下...

    hashin失效vumat_hashin破坏准则_vumatfailure_vumathashin失效_hashin_vumat

    在VUMAT中集成Hashin失效准则,可以精确模拟复合材料在不同载荷下的失效过程,例如在土木工程中预测结构在地震或风荷载下的响应,或者在航空航天领域分析飞行器的耐久性。 在“hashinʧ Чvumat.txt”这个文件中,...

    Redis 实践

    通过将图片ID分段,并使用前四位作为Hash结构的key,Instagram成功地将内存消耗降至每1,000,000条记录仅需16MB,总内存使用量降低至5GB,远低于最初的21GB,充分满足了业务需求。 #### 进一步的优化探索 在初步的...

Global site tag (gtag.js) - Google Analytics