`
yu06206
  • 浏览: 110120 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

浅谈哈希表

阅读更多

                                       浅谈哈希表
     之前学过hash表,当时对哈希表的的了解不是很深,经过这几天的深入分析,现在算是对哈希表有了一个比较浅的了解,
下面就简单的谈一下我对哈希表的了解,以后肯定还会对它进行深入的分析.
什么是哈希表?
     散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关
键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。通过自定义一个哈希表现在对哈希表这种结合数组和链表的优点的数据结构有了比较深的认识,解决了了数组插入速度慢,链表查询慢得问题。
系统中的hashMap与hashTable
      这里就不分析hashMap与hashTable的区别了,系统中HashMap的实例有两个参数影响其性能:初始容量 和加载因子。容
量是哈希表中桶的数量,初始容量只是哈希表在创建时的容量。加载因子 是哈希表在其容量自动增加之前可以达到多满的一种尺度。当哈希表中的条目数超出了加载因子与当前容量的乘积时,则要对该哈希表进行rehash 操作(即重建内部数据结构),从而哈希表将具有大约两倍的桶数。通常,默认加载因子 (.75) 在时间和空间成本上寻求一种折衷。加载因子过高虽然减少了空间开销,但同时也增加了查询成本(在大多数 HashMap 类的操作中,包括 get 和 put 操作,都反映了这一点)。在设置初始容量时应该考虑到映射中所需的条目数及其加载因子,以便最大限度地减少rehash 操作次数。如果初始容量大于最大条目数除以加载因子,则不会发生 rehash 操作,在自己实现的hash表中的改变加载因子确实会改变hash的性能,这个要具体的情况具体对待。
哈希函数
      系统中hashMap和hashtable使用的哈希函数不一样,hashMap使用的是h & (length-1)而hashTable使用的是很简单hash% table.length,至于为什么他们使用的是不同的哈希函数,这个其实是很大的学问,就像胡老师说的我们可以根据数理统计分析使用这两个哈希函数针对不同的数据他们分布概率,在我自己使用的hash表中对这两个hash函数进行了测试,我测试的结论是使用h & (length-1)函数的哈希冲突要少一些,这个可能和我的测试用例有关吧,我也自己根据网上的资料在自己的哈希表中使用一些不同的哈希函数,一下以字符串为例:

1.SDBMHash函数

	/**
	 * SDBMHash哈希函数
	 * @param v
	 * @return:hash索引
	 */

	public int SDBMHash(V v) {
		String str = (String) v;
		int hash = 0;
		char[] chars = str.trim().toCharArray();
		int count = 0;
		int length = chars.length;
		while (count < length) {
			hash = (int) chars[count] + (hash << 6) + (hash << 16) - hash;
			count++;
		}
		return (hash & 0x7FFFFFFF);
	}

 2.RS Hash函数

/**
	 *  RS Hash函数
	 * @param v
	 * @return
	 */

	public int RSHash(V v){
		int b = 378551;
		int a = 63689;
		int hash = 0;
		String str = (String) v;
		char[] chars = str.trim().toCharArray();
		int count = 0;
		int length = chars.length;
		while (count < length) {
			hash = (int) chars[count] + hash * a;
			a *= b;
			count++;
		}
		return (hash & 0x7FFFFFFF);

	}

  3.AP Hash函数

/**
	 * AP Hash函数
	 * @param v
	 * @return
	 */

	public int APHash(V v) {
		int hash = 0;
		String str = (String) v;
		char[] chars = str.trim().toCharArray();
		int i;
		for (i = 0; i < chars.length; i++) {
			if ((i & 1) == 0) {
				hash ^= ((hash << 7) ^ (hash >> 3));
			} else {
				hash ^= (~((hash << 11) ^ (hash >> 5)));
			}
		}
		return (hash & 0x7FFFFFFF);

	}

 4.ELFHash函数

/**
	 * ELFHash函数
	 * @param v
	 * @return
	 */
	public int ELFHash(V v){
		int hash = 0;
		int x = 0;
		String str = (String) v;
		char[] chars = str.trim().toCharArray();
		int count = 0;
		int length = chars.length;
		while (count < length) {
			hash = (int) chars[count] + (hash << 4);
			if ((x = (int) (hash & 0xF0000000L)) != 0) {
				hash ^= (x >> 24);
				hash &= ~x;
			}
			count++;
		}
		return (hash & 0x7FFFFFFF);
	}

 

以上的哈希函数都是针对字符串的,由于时间的关系还没有测试各个哈希函数的优缺点,希望大家有兴趣的话可以帮忙测试一下,对于哈希函数我总结一点:不同的情况不同对待!

Hash表的数据结构

       之前为了弄清楚系统中哈希表的数据结构,把系统中的源代码来来回回看了很多遍,理解也越来越深,最后看完之后不得不感叹系统对哈希表的设计真的是太好了,让我不得不赞叹,我不得不说我现在能想到的他都想到了,而且想的比我全面多了,最后只有是模仿系统的哈希表写了一个自己的哈希表,只是简化了很多东西,最后和系统的哈希表进行了一个简单的测试,测试结果让我很不服气,为什么呢?

 

哈希表的应用

      在做完哈希表后,稍微做了一下哈希表的应用,做了一个利用哈希表实现电话号码查询和存储的功能,非常简单,其实也可利用队列或者链表实现,但是用上哈希表之后查询或者删除数据肯定比较快速(这个没有测试),看一下截图:

 

  • 大小: 23 KB
  • 大小: 24.7 KB
分享到:
评论

相关推荐

    浅谈哈希表及哈希冲突.ppt

    浅谈哈希表及哈希冲突

    浅谈哈希表存储效率一般不超过50%的原因

    下面小编就为大家带来一篇浅谈哈希表存储效率一般不超过50%的原因。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    浅谈竞赛中哈希表的应用

    哈希表是一种高效的数据结构。本文分五个部分:首先提出了哈希表的优点,其次介绍了它的基础操作,接着从简单的例子中作了效率对比,指出其适用范围以及特点,然后通过例子说明了如何在题目中运用哈希表以及需要注意...

    IOI国家集训队论文集1999-2019

    + [哈希表](#哈希表) + [Splay](#splay) * [图论](#图论) + [图论](#图论-1) + [模型建立](#模型建立) + [网络流](#网络流) + [最短路](#最短路) + [欧拉路](#欧拉路) + [差分约束系统](#差分约束系统) + ...

    浅谈Java中的hashcode方法

    哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率。在Java的Object类中有一个方法:  public native int hashCode();  根据这个方法的声明可知,该方法返回一个int类型的...

    浅谈c# 泛型类的应用

    泛型类最常用于集合,如链接列表、哈希表、堆栈、队列、树等。 像从集合中添加和移除项这样的操作都以大体上相同的方式执行,与所存储数据的类型无关。对大多集合类的操作,推荐使用 .NET Framework 类库中所提供的...

    【JSON解析】浅谈JSONObject的使用

    简介 在程序开发过程中,在...“名称/值”对的集合(A Collection of name/value pairs),在不同的语言中,它被理解为对象(Object), 记录(record), 结构(struct), 字典(dictionary), 有趣列表(keyed list), 哈希表(hash

    浅谈SQL Server中的三种物理连接操作(性能比较)

    在SQL Server中,我们所常见的表与表之间的Inner Join,Outer Join都会被执行引擎根据所选的列,数据上是否有索引,所选数据的选择性转化为Loop Join,Merge Join,Hash Join这三种物理连接中的一种。理解这三种物理...

    Python核心编程第二版(ok)

     6.20 拷贝Python对象.c浅拷贝和深拷贝   6.21 序列类型小结   6.22 练习   第7章 映像和集合类型   7.1 映射类型:字典   7.1.1 如何创建字典和给字典赋值   7.1.2 如何访问字典中的值   ...

    Python核心编程(第二版).pdf (压缩包分2部分,第二部分)

     6.20 *拷贝python对象、浅拷贝和深拷贝   6.21 序列类型小结   6.22 练习   第7章 映像和集合类型   7.1 映射类型:字典   7.1.1 如何创建字典和给字典赋值   7.1.2 如何访问字典中的值   ...

    Python核心编程(第二版).pdf (压缩包分2部分,第一部分)

     6.20 *拷贝python对象、浅拷贝和深拷贝   6.21 序列类型小结   6.22 练习   第7章 映像和集合类型   7.1 映射类型:字典   7.1.1 如何创建字典和给字典赋值   7.1.2 如何访问字典中的值   ...

    Python核心编程第二版

     6.20 *拷贝Python对象、浅拷贝和深拷贝   6.21 序列类型小结   6.22 练习   第7章 映像和集合类型   7.1 映射类型:字典   7.1.1 如何创建字典和给字典赋值   7.1.2 如何访问字典中的值   ...

Global site tag (gtag.js) - Google Analytics