哈希表(散列表)——C++数据结构详解
目录
1.哈希表原理精讲
2.哈希链表算法实现
2.1哈希表数据结构定义
2.2哈希函数
2.3哈希链表初始化
2.4哈希链表查找函数
2.5哈希链表插入函数
2.6哈希链表删除元素
3.哈希表完整代码
哈希表 — 散列表,它是基于快速存取的角度设计的,也是一种典型的“空间换时间”的做法~
假设:给24个人依次给予编号,从1到24
编号除6能整除的为第一组: 6 12 18 24
编号除6余数为1的为第二组: 1 7 13 19
编号除6余数为2的为第三组: 2 8 14 20
编号除6余数为3的为第四组: 3 9 15 21
编号除6余数为4的为第五组: 4 10 16 22
编号除6余数为5的为第六组: 5 11 17 23
这样,当我们给出一个编号时,根据除6的余数,可以直接排除20个数据 ,从而更快速的找到他。
1.哈希表原理精讲
键(key) : 组员的编号 如,1、5、19.....
值(value):组员的其他信息(包含 性别、年龄、薪水等)
索引: 数组的下标(0,1,2,3,4),用以快速定位和检索数据
哈希桶: 保存索引的数组(链表或数组),数组成员为每一个索引值相同的多个元素
哈希函数:将组员编号映射到索引上,采用除余法,如:组员编号19
2.哈希链表算法实现
2.1哈希表数据结构定义
#define DEFAULT_SIZE 16 //索引数组范围,或者说哈希桶的个数typedef struct _ListNode {int key; //键值void* data; //数据struct _ListNode* next;
}ListNode;typedef ListNode* List;
typedef ListNode* Element;typedef struct _HashTable {int TableSize; ///索引数组范围,或者说哈希桶的个数List* Thelists;
}HashTable;
2.2哈希函数
//这里采用求余法做Hash函数
int Hash(int key, int TableSize) {return(key % TableSize);
}
2.3哈希链表初始化
//哈希表初始化 TableSize决定哈希桶的数量或者说索引范围
HashTable* InitHash(int TableSize) {int i = 0;HashTable* hTable = NULL;if (TableSize <= 0) {TableSize = DEFAULT_SIZE; //如果传入值小于0,就给予默认值}hTable = (HashTable*)malloc(sizeof(HashTable));if (NULL == hTable) {printf("HashTable malloc error\n");return NULL;}hTable->TableSize = TableSize;hTable->Thelists = NULL;//指针数组,指针的数组需要拿指针的指针接收hTable->Thelists = (List*)malloc(sizeof(List) * TableSize);if (NULL == hTable) {printf("HashTable malloc error\n");free(hTable);return NULL;}//为Hash桶对应的指针数组初始换链表节点for (int i = 0; i < TableSize; i++) {hTable->Thelists[i] = (ListNode*)malloc(sizeof(ListNode));if (NULL == hTable->Thelists[i]) {printf("HashTable malloc error\n");free(hTable->Thelists[i]);free(hTable);}else {//key赋值为0,值域(void*)和下一个指针赋为空memset(hTable->Thelists[i], 0, sizeof(ListNode));}}return hTable;
}
2.4哈希链表查找函数
Element findHash(HashTable** hashTable,const int key) {int index = 0;index = Hash(key, (*hashTable)->TableSize);List L = NULL; // L为对应哈希桶的指针L = (*hashTable)->Thelists[index];Element e = NULL;e = L->next; //e为对应值指针while (e!=NULL&&e->key!=key) {e = e->next;}return e;
}
2.5哈希链表插入函数
void insertHash(HashTable** hashTable, const int key, void* value) {Element insertElement = NULL;insertElement = findHash(hashTable, key);if (insertElement == NULL) {Element temp = NULL;temp=(Element)malloc(sizeof(ListNode));if (temp == NULL) {printf("malloc error\n");return;}temp->next = NULL;List L = (*hashTable)->Thelists[Hash(key, (*hashTable)->TableSize)];temp->data = value;temp->key = key;temp->next = L->next;L->next = temp;}else {printf("The key alerdy exist\n");}
}
2.6哈希链表删除元素
void deleteHash(HashTable* &hashtable, int key) {int index = Hash(key, hashtable->TableSize);List L = NULL;L = hashtable->Thelists[index];Element last = L;Element compareHash = NULL;compareHash = L->next;while (compareHash != NULL && compareHash->key != key) {last = compareHash;compareHash = compareHash->next;}if (compareHash != NULL) {last->next = compareHash->next;free(compareHash);}
}
测试程序:
int main() {char* a1 = (char*)"f张三";char* a2 = (char*)"李四";char* a3 = (char*)"王五";char* a4 = (char*)"赵六";char* arr[] = {a1,a2,a3,a4};HashTable* hashtable;hashtable = InitHash(17);insertHash(&hashtable, 1, arr[0]);insertHash(&hashtable, 2, arr[1]);insertHash(&hashtable, 3, arr[2]);insertHash(&hashtable, 4, arr[3]);deleteHash(hashtable, 1);for (int i = 0; i < 6; i++) {Element e = findHash(&hashtable, i);if (e) {printf("%s\n", (const char*)Retrieve(e));}else {printf("Not found [key:%d]\n", i);}}system("pause");return 0;
}
运行结果:
程序图示:
3.哈希表完整代码
#include<iostream>
using namespace std;#define DEFAULT_SIZE 16 //索引数组范围,或者说哈希桶的个数typedef struct _ListNode {int key; //键值void* data; //数据struct _ListNode* next;
}ListNode;typedef ListNode* List;
typedef ListNode* Element;typedef struct _HashTable {int TableSize; ///索引数组范围,或者说哈希桶的个数List* Thelists;
}HashTable;//这里采用求余法做Hash函数
int Hash(int key, int TableSize) {return(key % TableSize);
}//哈希表初始化 TableSize决定哈希桶的数量或者说索引范围
HashTable* InitHash(int TableSize) {int i = 0;HashTable* hTable = NULL;if (TableSize <= 0) {TableSize = DEFAULT_SIZE; //如果传入值小于0,就给予默认值}hTable = (HashTable*)malloc(sizeof(HashTable));if (NULL == hTable) {printf("HashTable malloc error\n");return NULL;}hTable->TableSize = TableSize;hTable->Thelists = NULL;//指针数组,指针的数组需要拿指针的指针接收hTable->Thelists = (List*)malloc(sizeof(List) * TableSize);if (NULL == hTable) {printf("HashTable malloc error\n");free(hTable);return NULL;}//为Hash桶对应的指针数组初始换链表节点for (int i = 0; i < TableSize; i++) {hTable->Thelists[i] = (ListNode*)malloc(sizeof(ListNode));if (NULL == hTable->Thelists[i]) {printf("HashTable malloc error\n");free(hTable->Thelists[i]);free(hTable);}else {//key赋值为0,值域(void*)和下一个指针赋为空memset(hTable->Thelists[i], 0, sizeof(ListNode));}}return hTable;
}Element findHash(HashTable** hashTable,const int key) {int index = 0;index = Hash(key, (*hashTable)->TableSize);List L = NULL; // L为对应哈希桶的指针L = (*hashTable)->Thelists[index];Element e = NULL;e = L->next; //e为对应值指针while (e!=NULL&&e->key!=key) {e = e->next;}return e;
}void deleteHash(HashTable* &hashtable, int key) {int index = Hash(key, hashtable->TableSize);List L = NULL;L = hashtable->Thelists[index];Element last = L;Element compareHash = NULL;compareHash = L->next;while (compareHash != NULL && compareHash->key != key) {last = compareHash;compareHash = compareHash->next;}if (compareHash != NULL) {last->next = compareHash->next;free(compareHash);}
}void insertHash(HashTable** hashTable, const int key, void* value) {Element insertElement = NULL;insertElement = findHash(hashTable, key);if (insertElement == NULL) {Element temp = NULL;temp=(Element)malloc(sizeof(ListNode));if (temp == NULL) {printf("malloc error\n");return;}temp->next = NULL;List L = (*hashTable)->Thelists[Hash(key, (*hashTable)->TableSize)];temp->data = value;temp->key = key;temp->next = L->next;L->next = temp;}else {printf("The key alerdy exist\n");}
}void* Retrieve(Element e) {return e ? e->data : NULL;
}
int main() {char* a1 = (char*)"f张三";char* a2 = (char*)"李四";char* a3 = (char*)"王五";char* a4 = (char*)"赵六";char* arr[] = {a1,a2,a3,a4};HashTable* hashtable;hashtable = InitHash(17);insertHash(&hashtable, 1, arr[0]);insertHash(&hashtable, 2, arr[1]);insertHash(&hashtable, 3, arr[2]);insertHash(&hashtable, 4, arr[3]);deleteHash(hashtable, 1);for (int i = 0; i < 6; i++) {Element e = findHash(&hashtable, i);if (e) {printf("%s\n", (const char*)Retrieve(e));}else {printf("Not found [key:%d]\n", i);}}system("pause");return 0;
}
哈希表(散列表)——C++数据结构详解相关推荐
- 数据结构:哈希表(散列表)基础
哈希表(散列表)基础 引入哈希表 什么是哈西表: 一种具有相同特性的数据元素的集合,每个元素具有唯一标识自己的关键字. 基本原理: 说明: 顺序查找.二分查找或者二叉树的查找是基于待查关键字与表中元素 ...
- 2.10_hash_table_哈希表 / 散列表
链表类 class LinkedList(object):"""链表类"""class Node(object):def __init__( ...
- 哈希表(散列表)原理详解
什么是哈希表? 哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度 ...
- 【数据结构笔记39】哈希表/散列表、(数据关键字/字符串关键字)散列构造函数
本次笔记内容: 11.1.1 引子:散列的基本思路 11.1.2 什么是散列表 11.2.1 数据关键词的散列函数构造 11.2.2 字符串关键词的散列函数构造 文章目录 散列表背景 基本思想引出 已 ...
- 算法小讲堂之哈希表|散列表|考研笔记
文章目录 一. 基本概念 二. 哈希函数|散列函数 2.1 直接定址法 2.2 保留余数法 2.3 数字分析法 2.4 平方取中法 2.5 折叠法 2.6 随机数法 三.冲突处理 3.1 开放定址法 ...
- 开局一张图帮你充分理解哈希表(散列表)
目录 1哈希表的概念: 1.1哈希表的插入图示: 1.2哈希表的查询图示: 2.哈希冲突 2.1哈希冲突的概念: 2.2避免冲突 2.2.1哈希函数设计 2.2.2负载因子的调节 3.解决冲突 3.1 ...
- 哈希表(散列表)介绍
目录 前言 一.哈希概念 1.1 什么时哈希表 1.2 哈希函数 1.3 哈希冲突 1.4 哈希冲突的解决 1.4.1 闭散列 1.4.2 开散列 1.4.3 问题 前言 哈希表时C++11两容器un ...
- JavaScript 哈希表(散列表)实现和应用
查找的效率与比较次数密切相关.基于比较的程序,运算效率是比较低的.比如平时可以通过indexOf查找一个数据.但这是一个基于比较的一个实现.如果是淘宝那样有上亿个商品,那么用indeOf 来查数据就会 ...
- 【数据结构与算法】哈希算法的原理和应用详解!
在程序员的实际开发中,哈希算法常常能用得到,本文以哈希算法的原理和应用为核心,和大家详细讲解一下哈希算法的概念.常见算法以及原理.在信息安全的应用等等. 一.概念 哈希表就是一种以 键-值(key-i ...
最新文章
- 201621123069 《Java程序设计》第十一周学习总结
- 我们曾探讨过的微信功能
- Geoserver怎样设置地图shp文件为相对路径,可轻松复制移植
- scm maven_在运行时访问工件的Maven和SCM版本
- 酷6暴力裁员,是清洗也是重塑
- 瑞晟蓝牙来电语音软件下载_拥有无数功能的工具箱软件
- Microsoft Surface--Bing™ Maps WPF Control
- Java字符字符串类
- 实验2-1-5 将x的平方赋值给y (5 分)
- java char 比较,为什么我在Java中使用char和int进行比较?
- java session时间_java设置session过期时间的实现方法
- java 返回进度条_Java中的命令行进度条
- 有关sim800l的资料
- iOS开发 ----- 加载动画之牛顿摆的实现
- 关键点检测——无监督
- 第三方直播SDK对比|直播SDK如何选型
- 快慢指针的概念及其应用
- 《Python深度学习》第一部分读书笔记
- 【数据处理】Python,matplotlib 如何画柱状图?如何画各种类型的柱状图?柱子宽度设置;设置X轴刻度用label显示;设置柱子距离x轴的高度;设置柱体颜色;设置柱体描边;并列、多条柱状图
- 一个40岁老码农的总结,奋斗没有意义,选择大于努力
热门文章
- html css文字标题特效,CSS 实现漂亮的大标题效果
- C语言入门——《明解C语言》入门篇第四章练习
- 顶尖电子秤ls6恢复出厂_顶尖电子称怎么恢复出厂默认?
- SpringBoot整合Activiti7
- js视频背景切换js特效代码
- STM32学习(窗口看门狗)
- 计算机应用计算题(61),计算机应用模拟试题及答案
- bytedance怎么读_我被字节的HR骗了...
- 国际互联网计算与物联网大会ICOMP 2017高度赞誉DroiBaaS全栈式优化架构
- 2011年30家最能赚钱移动互联公司排行榜