IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> Hash哈希表的全新理解 -> 正文阅读

[数据结构与算法]Hash哈希表的全新理解

一、Hash哈希表

无论是栈、队列、还是顺序表等线性结构中,记录的关键字和存储位置之间都不存在一 一对应的关系。在查找记录的时候,则需要对关键字进行逐一比对,过程繁琐,查找效率低。
哈希表是一种高效的查找结构,它的出现很好地解决了这个问题,接下来让我们逐步深入学习。

二、哈希函数

哈希函数是哈希表的灵魂,正因为它的存在,哈希表才完成了从记录关键字到存储位置的一一映射关系。类比y=f(x),存储位置作为因变量是由自变量关键字经过某种函数关系计算而得的。

哈希函数的构造方法:

  1. 直接定址法(y=x):不作变换,直接使用关键字作为哈希地址。
  2. 除留余数法(y=x%a,其中a为常数)
  3. 数字分析法:在关键字中选择分布均匀的位数作为哈希地址(这种方法观察主观选择,与函数无关)
  4. 折叠法
  5. 平方取中法

三、冲突以及处理冲突的方法

首先什么叫冲突?
我们都知道想y=x^2,当y=1时方程有两个解1或者-1。可是如果“1”代表的是唯一的存储地址1,那么这时候究竟是存放“1”还是“-1”呢?(冲突,也就这样产生了)
想要解决冲突就是要解决两个解如何存放的问题(一山不能容二虎)。

  • 链地址法:

平时操场集合的时候,前面排列着各个班的班牌(有且只有一个),每个班都不止一位同学,如何大家都站在班牌那,这就发生了冲突,所以该如何站呢?
很简单,以班牌为地址,同班同学在同一列,逐一向后排列即可。

同样的道理,如果我们能在存储地址1的下方放置另一个解“-1”,依此类推,那冲突的问题就解决了。

因此,我们需要创建一个指针数组,指针数组里的每个元素就好像是操场上的班牌一样,指向着整个班,而后,每个记录都采用链表结点的方式,在同一“班牌”下的记录,按先来后到的方式链接在后面。
如图:
在这里插入图片描述

  • 开放地址法:
    既然哈希函数可以实现记录关键字和存储位置的一一对应,那我们直接可以新建一个处理冲突的函数(y=x^2-1或者其他可以改变y的函数),这样子,实现了多个解发生冲突的时候,可以错开存放。
    在这里插入图片描述
    另外,
    根据所选的冲突函数不同,又分为线性探测法二次探测法(y=x^(2) -a ^(2))

四、哈希表的实现

根据不同的处理冲突的方法,哈希表可以分成两类链地址哈希表开放定址哈希表
(本次主要介绍链地址哈希表,下一讲再介绍开放定址哈希表)

链地址哈希表类型定义:

 typedef struct {
	KeyType key;	//KeyType为新定义类型,方便多种关键字转换 
}RcdType; //记录的结构
typedef struct Node {
	RcdType r;
	struct Node *next;
}Node;	//结点的结构
typedef struct {
	Node **rcd;
	int size;
	int count;
	int (*hash)(KeyType key,int size);//函数指针,可以指向整形,含有两个参数的函数
}Hash;	//哈希表的结构

链地址哈初始化:

//链地址哈希表初始化 
Status InitHash (Hash &H,int size,int (*hash)(int,int)) { //Status 认为定义类型,方便多种类型间转换 
	H.rcd = (Node**)malloc(size*sizeof(Node*));
	if (NULL==H.rcd) {
		return ERROR;
	}
	else {
		for (int i=0;i<size;i++) H.rcd[i] =NULL;	//注意区分H.rcd=NULL;
		H.size = size;
		H.count = ERROR;
		H.hash = hash;
		return ERROR;
	}
}

查找记录:

Node * SearchHash(Hash &H,int key) {
	//使用哈希函数 
	int h = hash(key,H.size);
	Node *p ;
	for (p = H.rcd[h];p!=NULL;p = p->next) {
		if (p->r.key==key) return p;
	}
	return NULL;
}

在表头插入记录:

Status InsertHash (Hash &H,RcdType e) {
	if (SearchHash(H,e.key)==NULL) {
		int h = hash(e.key,H.size);
		Node *p ;
		p->r = e;
		p->next = H.rcd[h];
		H.rcd[h] = p;
		H.count++;		//成功插入后,哈希表内记录数+1;
		return OK;
	} 
	else {
		return FALSE;
	} 
} 

删除记录:

Status  DeleteHash (Hash &H,int key,RcdType &e) {
	Node *p = SearchHash(H,e.key);
	if (p==NULL) {
		return 0; 
	} 
	else {
		key = p->r.key;
		int h = hash(e.key,H.size);
		Node *pr;
		while (pr->next!=p) {
			pr = pr->next;
		}
		pr = p->next;
		free(p);
		H.count--;
		return key;
	}
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-11-24 08:12:21  更:2021-11-24 08:13:30 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 12:29:49-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码