`

Hash表

阅读更多
哈希表总结
一、哈希表的概念及作用
一般的线性表,树中,记录在结构中的相对位置是随机的,即和记录的关键字之间不存在确定的关系,因此,在结构中查找记录时需进行一系列和关键字的比较。这一类查找方法建立在“比较“的基础上,查找的效率依赖于查找过程中所进行的比较次数。
理想的情况是能直接找到需要的记录,因此必须在记录的存储位置和它的关键字之间建立一个确定的对应关系f,使每个关键字和结构中一个唯一的存储位置相对应。
冲突现象:不同的关键字可能得到同一哈希地址。
二、哈希表的构造方法
1.直接定址法  哈希码就是关键字自身
2.数字分析法
有学生的生日数据如下:75.10.03   75.11.23 76.03.02
经分析,第一位,第二位,第三位重复的可能性大,取这三位造成冲突的机会增加,所以尽量不取前三位,取后三位比较好。
3.平方取中法
取关键字平方后的中间几位为哈希地址。
4.折叠法
将关键字分割成位数相同的几部分(最后一部分的位数可以不同),然后取这几部分的叠加和(舍去进位)作为哈希地址,这方法称为折叠法。
例如:如果一本书的编号为0-442-20586-4,则:
5864                          5864
4220                          0224
+) 04                    +)  04
-----------              -----------
10088                         6092
H(key)=0088 H(key)=6092

(a)移位叠加 (b)间界叠加
5、除留余数法
取关键字被某个不大于哈希表表长m的数p除后所得余数为哈希地址。
H(key)=key MOD p (p<=m)
6、随机数法
选择一个随机函数,取关键字的随机函数值为它的哈希地址,即
H(key)=random(key) ,其中random为随机函数。通常用于关键字长度不等时采用此法。
二、处理冲突的方法
1、开放定址法
Hi=(H(key)+di) MOD m i=1,2,...,k(k<=m-1)其中m为表长,di为增量序列
如果di值可能为1,2,3,...m-1,称线性探测再散列。
如果di取值可能为1,-1,2,-2,4,-4,9,-9,16,-16,...k*k,-k*k(k<=m/2) 称二次探测再散列。
如果di取值可能为伪随机数列。称伪随机探测再散列。
2、再哈希法
当发生冲突时,使用第二个、第三个、哈希函数计算地址,直到无冲突时。缺点:计算时间增加。
3、链地址法
将所有关键字为同义词的记录存储在同一线性链表中。
4、建立一个公共溢出区
除基本表外,另外设立存储空间向量OverTable[0..v]用以存储发生冲突的记录。

哈希表实现
/*数据项类
 用来表示数据*/
class DataItem {
	int key;
	String value;

	public DataItem() {
	}
	public DataItem(int t, String e) {
		this.key = t;
		this.value = e;
	}
	public int getKey() {
		return this.key;
	}
	public String getValue() {
		return this.value;
	}
}
/*
 * 产生聚集时使用的线性查找
 */
public class HashTableTest {
	private DataItem[] hashArray = null;// 数组
	private int arraySize = 0;// 数组大小
	private int currentSize=0;
	private DataItem nonItem = null;

	/* 哈希表初始化 */
	public HashTableTest(int size) {
		arraySize = size;
		hashArray = new DataItem[size];
	}

	// 输出表
	public void displayTable() {
		for (int i = 0; i < arraySize; i++) {
			if (hashArray[i] != null)
				System.out.print(hashArray[i].getKey() + " ");
			else
				System.out.print("* ");
		}
		System.out.println();
	}

	// 哈希函数,计算哈希码
	private int hashFunction(int key) {
		return key % arraySize;
	}
	private int hashFunctionDouble(int key){
		return 5-key%5;
	}
	// 插入新元素
	public void insert(DataItem item) {
		int key = item.getKey();
		int hashVal = this.hashFunction(key);//计算哈希码
		// int stepSize=this.hashFunctionDouble(key);//重散列
		while (hashArray[hashVal] != null) {
			
			hashVal++;//线性探测
			hashVal %= arraySize;
			
			/*hashVal+=stepSize;
			hashVal%=stepSize;*/	//重散列
			if(currentSize>arraySize){
				System.out.println("HashTable已满,插入失败!");
				break;
			}
			currentSize++;
		}
		if(currentSize<=arraySize)hashArray[hashVal] = item;
	}

	// 查找元素
	public DataItem find(int key) {
		int hashVal = this.hashFunction(key);
		while (hashArray[hashVal] != null) {
			if (hashArray[hashVal].getKey() == key)
				return hashArray[hashVal];
			hashVal++;
			hashVal %= arraySize;
			
			/*hashVal+=stepSize;
			hashVal%=stepSize;*/	//重散列
					
			if(hashVal==this.hashFunction(key))break;
		}
		System.out.println("查找失败!");
		return null;
	}
	public DataItem delete(int key){
		int hashVal=this.hashFunction(key);
		while(hashArray[hashVal]!=null){
			if(hashArray[hashVal].getKey()==key){
				DataItem item=hashArray[hashVal];
				hashArray[hashVal]=null;
				return item;
			}
			hashVal++;
			hashVal%=arraySize;
			
			/*hashVal+=stepSize;
			hashVal%=stepSize;*/	//重散列
			
			if(hashVal==this.hashFunction(key))break;
		}
		return null;
	}
	public static void main(String[] args) {
		int size = 10;
		DataItem item;
		HashTableTest hash = new HashTableTest(size);
		for (int i = 0; i < size; i++) {
			item = new DataItem(i, i + "zzq" + i);
			hash.insert(item);
		}
		hash.displayTable();
		item = new DataItem(11, 11 + "zzq" + 11);
		hash.insert(item);
		hash.displayTable();
		item = hash.find(1);
		System.out.println(item == null);

	}
}
分享到:
评论

相关推荐

    hash表的应用

    Hash表应用 (必做) (查找) [问题描述]  设计散列表实现身份证查找系统,对身份证号进行Hash。 [基本要求] (1) 设每个记录有下列数据项:身份证号码(虚构,位数和编码规则与真实一致即可)、姓名、地址; ...

    C语言实现的Hash表(代码)

    C语言实现的Hash表(代码)。C语言实现的Hash表(代码)。C语言实现的Hash表(代码)。C语言实现的Hash表(代码)。

    c语言hash表源码

    c语言hash表源码 来自于开源软件项目

    双向链表与hash表

    从linux内核提取出来的,双向链表和hash表实现。在普通的用户态C程序中,均可使用

    HASH_hash_stm32hash_stm32hash表_stm32f407_

    stm32f407平台上实现的hash算法

    自己实现的hash表

    自己实现的hash表,自己的hash函数,优化了的内存管理

    C#两级嵌套hash表

    封装hashtable的两级hash表,两个键值索引和访问。适合存放稀疏数据,如稀疏矩阵,稀疏表等结构,由于提供key-value的索引遍历,数据稀疏的情况下,相比于传统矩阵遍历的速度更快。

    Hash表模板类

    C++写的hash表模板类,效率还是很不错的。另付有测试代码和可运行文件

    打造最快的Hash表

    打造最快的Hash表.doc 据说来自暴雪 nop nop nop nop

    基于HASH表和SYN计算的TCP包重组方法.rar

    基于HASH表和SYN计算的TCP包重组方法.rar

    hash表操作

    该文档消息描述了hash表的创建、数据插入、数据删除、数据查找以及hash表销毁等操作

    Hash表的分析以及组成原理解析及代码实现.md

    Hash表采用了数组加链表的结构,即一个数组元组中不再是存储单个元素,而是存储一个链表,就好比包租婆收租的时候,一个握把上面挂了一连串的钥匙一样。Hash表的引出是为了减少查询数据库操作所带来的时间问题,将...

    数据结构作业Hash表

    数据结构第16次作业,hash表 Spellchecking Prerequisites, Goals, and Outcomes Prerequisites: Students should have mastered the following prerequisite skills. • Hash Tables - Understanding of the ...

    基于Hash表的代码相似度度量

    本人的数据结构实习作业“基于Hash表的代码相似度度量”,代码简洁明了,可读性强,并附带较多的注释,方便他人查看。一般通过查看注释便能了解程序的结构与功能,方便进行修改。以下是实习作业的具体要求: 对于两...

    hash表学习基础程序

    简单的hash学习程序。 关于Hash的详细介绍请见我的文章http://blog.csdn.net/yankai0219/article/details/8185796

    uthash表操作函数

    hash表操作函数 HASH_ADD_INT HASH_ADD_STR

    base64和hash表

    base64加解密, hash表, fnmatch的windows下的实现简单实现版本。是从mosquitto的auth_plug中copy和https://blog.csdn.net/tttmt/article/details/24824291?utm_source=blogxgwz8 看到的 c语言代码。在qt上测试了

    hash表设计

    hash表的源代码#include &lt;stdio.h&gt; /*标准输入输出函数库*/ #include&lt;stdlib.h&gt; /*标准函数库*/ #include&lt;string.h&gt; #define HASH_LEN 50 /*哈希表的长度 */ #define M 47 #define NAME_N 30 /*人名拼音的最大个...

Global site tag (gtag.js) - Google Analytics