数据结构之哈希表
1.哈希表简介
2.冲突
3.重载因子
4.一些常用的Hash算法
1.先来看看哈希表在百度百科的解释,哈希表是根据关键码值而直接经行访问的数据结构。也就是说,他通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数。
其中有些关键字:关键值...数据结构....映射.....查找速度
简单的说,哈希表是一种比普通查找方法查找起来更快的数据结构,他是一种数据结构,他的存储方法是通过一组数据(key)的映射来决定的,所以只要能得到这组数据,那么就能根据自己设定的映射方式(一般我们叫做哈希函数)来直接算出该数据存储的位置,以达到快速查找的目的。利用这种存储结构,可以更快的查找到我们要查找的数据。
1.冲突,由于存储地址是有限的和固定的,那么在我们的映射方式(哈希函数)对于多个key值经行映射时,就会可能有多个key值同时算出来一个地址,这种现象叫做冲突,解决冲突的方式很多,简要介绍几种方式
1.再散列法,就是在发生冲突时,将容器改变,重新经行哈希,直到不产生冲突为止。
2.链地址法,在产生冲突时,在原来的地址上建立一个链表。
3.建立公共溢出区,把产生冲突的数据,全部储存到一块区域里去。
这里主要讲链地址法。
2.重载因子,在链地址法处理冲突时,其实是用空间换取时间,数组下面建立链表,这样既拥有了数组的方便寻址,又有链表的方便增删。冲突的频率过于频繁,而当冲突同时发生在同意区域时,其实就形成了一支链表,这样就根本不能达到减少查找时间的效果,所以我们要控制某一支链表的长度,当某一支链表超过某个比例时,我们应当做某些处理,以减少查找时间,增加查找效率。这个比例我们乘坐重载因子,当某一支链表的长度比上整个数组的的长度大于重载因子时,将数组扩容,所有元素重新排列,称之为再哈希。这个重载因子决定了查找的效率,太大查找效率会偏低,太小会导致再哈希过于频繁,浪费时间。据科学家计算过,当重载因子为0.75时,算法效率最高。
3.哈希算法
1.直接寻址法 根据key值用某个线性函数获取地址
2.数字分析法 利用重复数字较少的部分构成散列地址,减少冲突
3.平法取中法 关键字平方后去中间几位作为散列地址
4.除留取余法 取某个值p,用key值除p得到的值取余数作为散列地址
5.随机数法 取一组随机数作为散列地址
这些方法是平时一般比较常用的方法,说到这里的话,我想大家都已经懂了,利用key值映射得到地址,然后去相应的地址里找。就像是一道脑筋急转弯,我告诉你老师所在的楼层是key的三倍加一,然后告诉你key是2,你能知道老师在那个楼层么,2是已经给出的key,3x+1是哈希函数,利用函数寻找地址就是这个意思。ok,献上一段链地址法的代码,哈希函数是平方取余
public class Hash {
private Maping[] array ; //存储数组
private double factor = 0.7; //装载因子
private int count = 10; //默认装载个数
private int enough = 6; //超出后的添加数
/**
* 使用默认构造器,构造一个Hash
*/
public Hash(){
array = new Maping[count];
}
/**
* 使用自定义的构造器,构造Hash
* @param count 自定义的初始装载个数
* @param factor 自定义的装载因子
*/
public Hash(int count,float factor){
this.count = count;
this.factor = factor ;
array = new Maping[count];
}
/**
* 跟据数据的key值查找
* @param key 映射的key值
* @return 返回元素的value值,如果不存在,返回null
*/
public Object searchValue(int key){
//计算出该元素所存在的数组索引
int code1 = getHashCode(key);
//根据索引所在的数组元素,往链表之下寻找
Maping temp = array[code1];
while(temp != null){
//如果找到元素,返回value值
if(temp.getData() == key){
return temp.getValue();
}//如果没找到,继续往下找
else{
temp = temp.getNext();
}
}
return null;
}
/**
* 添加一个数据进入Hash,该Hash允许相同的value值的存在,未处理相同key值的存在(原则上讲不允许相同的key值)
* @param m 要添加的元素
*/
public void add(Maping m){
int xCount = 1; //记录该条链上所拥有的元素个数
//利用自己写的Hash函数,获取在数组中应存放的位置
int code1 = getHashCode(m.getData());
//如过为空,将他放在里边
if(array[code1]==null){
array[code1] = m;
}//如果不为空
else{
//一直找到链表的末尾,将新添加的元素放在队尾
Maping temp = array[code1];
xCount++;
while(temp.getNext() != null){
xCount++;
temp = temp.getNext();
}//添加进入队尾
temp.setNext(m);
m.setNext(null);
}
//如果链表长度超过了比例,也就是超过重载因子的限制,那么就重新排列reHash
if((double)xCount/(double)count>factor){
reHash();
}
}
/**
* 利用自己写的Hash函数,获取应存放的位置
* 其实这只是一个简单的映射,这种映射可以随自己的意愿更改
* @param data 函数的利用值
* @return 返回得到的Code值
*/
public int getHashCode(int data){
//平方取余法
int value = (data*data)%count;
return value;
}
/**
* 由于装载数超过装载因子数目,重新把元素提出,将数组扩容,再次Hash
*/
public void reHash(){
//将已有的Hash中的数据全部存储起来
List<Maping> list = new ArrayList<Maping>();
for(int i=0;i<array.length;i++){
Maping temp = array[i];
while(temp != null){
Maping temp1 = temp.getNext();
//把得到的节点隔离出来
temp.setNext(null);
list.add(temp);
//赋值,还原指针
temp = temp1;
}
}
//重置Hash数组,并改变容量
count = count + enough;
array = new Maping[count];
//重新添加
for(int i=0;i<list.size();i++){
Maping m = list.get(i);
add(m);
}
}
/**
* 打印当前的Hash表(测试用)
*/
public void print(){
for(int i=0;i<array.length;i++){
System.out.println(i+"---->");
if(array[i]==null){
continue;
}
else {
Maping temp = new Maping(0, "temp");
temp = array[i];
while(temp != null){
System.out.println(temp.getData()+" "+temp.getValue());
temp = temp.getNext();
}
}
System.out.println();
}
}
}
分享到:
相关推荐
在这个“数据结构之哈希表”的实验中,主要目标是设计并实现一个基于哈希表的电话号码查询系统。以下是实验中涉及的主要知识点: 1. **哈希函数**:哈希函数是哈希表的核心,它负责将键转换为数组索引。在实验中,...
数据结构中的哈希表是一种高效的数据存储和检索结构,它通过特定的哈希函数将关键字映射到数组的索引位置,实现快速访问。在这个实验报告中,我们关注的是如何构建哈希表并进行基本操作,包括插入、删除、查找等。 ...
针对某个集体(比如你所在的班级)中的“人名”设计一个哈希表,使得平均查找长度不超过R,完成相应的建表和查表程序。 假设人名为中国人姓名的汉语拼音形式。待填入哈希表的人名共有30个,取平均查找长度的上限为2...
Java数据结构 线性表,链表,哈希表是常用的数据结构,在进行Java开发时,JDK已经为我们提供了一系列相应的类来实现基本的数据结构
数据结构课设 哈希表 C++源码 需要的拿去
在“数据结构哈希表设计实验报告”中,我们可能会涉及到以下几个关键知识点: 1. **哈希函数**:哈希函数是哈希表的核心,它的作用是将键转化为数组的索引。一个好的哈希函数应该尽可能使得不同的键映射到不同的...
哈希表是一种高效的数据结构,它通过特定的函数——哈希函数,将任意大小的键(key)映射到一个固定大小的数组中,从而实现快速查找、插入和删除操作。在“数据结构试验:哈希表设计”中,我们将探讨哈希表的基本...
哈希表是一种高效的数据结构,主要用于快速查找和存储数据。它通过哈希函数将数据映射到一个固定大小的数组中,以达到快速访问的目的。哈希冲突是哈希表面临的主要挑战,解决冲突的方法有开放寻址法、链地址法等。 ...
哈希表是一种高效的数据结构,它通过特定的哈希函数将键(Key)映射到一个固定大小的数组中,以此实现快速的查找、插入和删除操作。在数据结构领域,哈希表是解决查找问题的重要工具,尤其适用于大数据量且需要频繁...
哈希表,也被称为散列表,是一种非常重要的数据结构,它在计算机科学中扮演着关键角色,尤其是在存储和检索大量数据时。哈希表通过使用哈希函数将键(Key)映射到数组的索引位置,实现了快速的查找、插入和删除操作...
哈希表是一种高效的数据结构,它通过特定的哈希函数将键(key)映射到一个固定大小的数组中,以此实现快速查找、插入和删除等操作。在数据结构设计中,哈希表是一个重要的组成部分,尤其对于大量数据的处理,它的...
数据结构里哈希表的实验报告 构造二叉树,构造哈希表等 c语言版
### 数据结构中的哈希表查找 #### 哈希表简介 哈希表(Hash Table)是一种基于数组的数据结构,它通过将关键字映射到数组的某个位置来存储和检索数据,这种映射过程通常由一个哈希函数完成。哈希表能够实现快速的...
### 数据结构:C语言实现哈希表 #### 核心知识点概述 本篇文章将围绕一个C语言中的哈希表实现案例展开,详细解析哈希表的基本概念、设计思路及其实现过程。通过阅读本文,您将了解到哈希表在C语言编程中的应用,并...
哈希表和二叉树是数据结构中两个重要的概念,它们在存储和检索数据时具有各自的优势和应用场景。本文将详细探讨这两种数据结构,并通过C++实现来加深理解。 首先,我们来了解一下哈希表。哈希表,又称散列表,是一...
哈希表的代码,可以用于数据结构试验交作业或者用于写实验报告
哈希表,又称散列表,是数据结构课程中一种非常重要的数据存储结构,它通过将关键字(key)映射到数组的索引位置来实现快速的查找、插入和删除操作。在本课程设计中,我们将深入理解哈希表的原理,并亲手实现一个...
哈希表,也被称为散列表,是数据结构中一种高效的数据存储和检索工具。它通过哈希函数将数据的关键字映射到一个固定大小的数组中,使得在平均情况下,查找、插入和删除操作的时间复杂度可以达到O(1)。这种高效的性能...
哈希表课程设计数据结构实验报告——哈希表设计 针对某个集体中的人名设计一个哈希表,使得平均查找长度不超过R,完成相应的建立和查表程序. 1.2 人名为汉语拼音形式,最长不超过18个字符(如:庄双双 ...