哈希表总结
一、哈希表的概念及作用
一般的线性表,树中,记录在结构中的相对位置是随机的,即和记录的关键字之间不存在确定的关系,因此,在结构中查找记录时需进行一系列和关键字的比较。这一类查找方法建立在“比较“的基础上,查找的效率依赖于查找过程中所进行的比较次数。
理想的情况是能直接找到需要的记录,因此必须在记录的存储位置和它的关键字之间建立一个确定的对应关系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表是一种数据结构,它通过使用哈希函数将键(key)映射到数组的索引位置,从而实现快速的查找、插入和删除操作。在C语言中,我们可以利用结构体和指针来构建一个简单的Hash表。下面将详细介绍Hash表的概念、哈希...
Hash表应用 (必做) (查找) [问题描述] 设计散列表实现身份证查找系统,对身份证号进行Hash。 [基本要求] (1) 设每个记录有下列数据项:身份证号码(虚构,位数和编码规则与真实一致即可)、姓名、地址; ...
"基于HASH表和SYN计算的TCP包重组方法"是一种优化的重组策略,旨在提高数据恢复的效率和准确性。 TCP报文段重组的核心是确保数据的正确性和完整性。在传统的TCP实现中,通常使用滑动窗口协议来跟踪接收到的报文段,...
在"hash表模板类"这个压缩包中,你可能找到了一个实现了以上功能的C++源文件。通过阅读和理解代码,你可以学习到自定义哈希表的实现细节。此外,附带的测试代码和可运行文件可以帮助你验证该哈希表模板类的正确性,...
在STM32F407上实现的哈希(Hash)算法是数字签名、数据完整性验证等安全应用中的关键组成部分。哈希算法能够将任意长度的输入数据转化为固定长度的输出,通常称为哈希值或消息摘要。 哈希算法的主要特性包括: 1. *...
封装hashtable的两级hash表,两个键值索引和访问。适合存放稀疏数据,如稀疏矩阵,稀疏表等结构,由于提供key-value的索引遍历,数据稀疏的情况下,相比于传统矩阵遍历的速度更快。
哈希表(Hash Table)是一种数据结构,它通过计算一个关联数组中的索引来确定一个特定元素的存储位置,使得在平均情况下,查找、插入和删除操作的时间复杂度达到O(1)。C语言中的哈希表实现是程序员常用的数据结构...
Hash表是一种在计算机科学中广泛使用的数据结构,它通过一种特定的哈希函数将键(Key)映射到数组的索引位置,从而实现快速的查找、插入和删除操作。在游戏开发,尤其是在大型在线游戏中,高效的数据存储和检索对于...
"Hash表的建立和查找" Hash表是一种高效的数据结构,它通过哈希函数将关键字映射到索引上,以便快速地存储和查找数据。Hash表的建立和查找是数据结构课程的重要内容,本文将详细介绍Hash表的建立和查找的知识点。 ...
### 打造最快的Hash表(和Blizzard的对话) #### Hash表基础知识与应用场景 本文将深入探讨如何构建高效的Hash表,并特别关注Blizzard在游戏开发过程中所采用的技术。Hash表是一种利用散列函数来实现快速查找的数据...
该文档消息描述了hash表的创建、数据插入、数据删除、数据查找以及hash表销毁等操作
链地址Hash表的代码实现 链地址Hash表是一种常用的Hash算法,它的优点在于可以快速查找数据,同时占用的内容空间也非常小。 链地址Hash表的实现可以分为四个步骤: 1. 定义Hash表和基本数据节点 在这里,...
在编程领域,哈希表(Hash Table)是一种高效的数据结构,它通过特定的哈希函数将数据映射到一个固定大小的数组中,以实现快速的查找、插入和删除操作。哈希表的关键在于设计良好的哈希函数,该函数能够尽可能均匀地...
hash表操作函数 HASH_ADD_INT HASH_ADD_STR
Hash表采用了数组加链表的结构,即一个数组元组中不再是存储单个元素,而是存储一个链表,就好比包租婆收租的时候,一个握把上面挂了一连串的钥匙一样。Hash表的引出是为了减少查询数据库操作所带来的时间问题,将...
哈希表(Hash Table)是一种数据结构,它通过哈希函数将输入(通常是字符串)映射到一个固定大小的数组的索引上,使得数据的查找、插入和删除操作能够达到近乎常数时间的复杂度,即O(1)。在编程中,哈希表的高效性能...
`study-hash`这个文件可能是对哈希表学习的代码实现,包括了哈希函数的设计、冲突处理方法的实现,以及可能的一些性能测试。通过阅读和理解这个程序,你可以更深入地掌握哈希表的工作原理和实际运用。在实践中,不断...
数据结构第16次作业,hash表 Spellchecking Prerequisites, Goals, and Outcomes Prerequisites: Students should have mastered the following prerequisite skills. • Hash Tables - Understanding of the ...