目录

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++数据结构详解相关推荐

  1. 数据结构:哈希表(散列表)基础

    哈希表(散列表)基础 引入哈希表 什么是哈西表: 一种具有相同特性的数据元素的集合,每个元素具有唯一标识自己的关键字. 基本原理: 说明: 顺序查找.二分查找或者二叉树的查找是基于待查关键字与表中元素 ...

  2. 2.10_hash_table_哈希表 / 散列表

    链表类 class LinkedList(object):"""链表类"""class Node(object):def __init__( ...

  3. 哈希表(散列表)原理详解

    什么是哈希表?    哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度 ...

  4. 【数据结构笔记39】哈希表/散列表、(数据关键字/字符串关键字)散列构造函数

    本次笔记内容: 11.1.1 引子:散列的基本思路 11.1.2 什么是散列表 11.2.1 数据关键词的散列函数构造 11.2.2 字符串关键词的散列函数构造 文章目录 散列表背景 基本思想引出 已 ...

  5. 算法小讲堂之哈希表|散列表|考研笔记

    文章目录 一. 基本概念 二. 哈希函数|散列函数 2.1 直接定址法 2.2 保留余数法 2.3 数字分析法 2.4 平方取中法 2.5 折叠法 2.6 随机数法 三.冲突处理 3.1 开放定址法 ...

  6. 开局一张图帮你充分理解哈希表(散列表)

    目录 1哈希表的概念: 1.1哈希表的插入图示: 1.2哈希表的查询图示: 2.哈希冲突 2.1哈希冲突的概念: 2.2避免冲突 2.2.1哈希函数设计 2.2.2负载因子的调节 3.解决冲突 3.1 ...

  7. 哈希表(散列表)介绍

    目录 前言 一.哈希概念 1.1 什么时哈希表 1.2 哈希函数 1.3 哈希冲突 1.4 哈希冲突的解决 1.4.1 闭散列 1.4.2 开散列 1.4.3 问题 前言 哈希表时C++11两容器un ...

  8. JavaScript 哈希表(散列表)实现和应用

    查找的效率与比较次数密切相关.基于比较的程序,运算效率是比较低的.比如平时可以通过indexOf查找一个数据.但这是一个基于比较的一个实现.如果是淘宝那样有上亿个商品,那么用indeOf 来查数据就会 ...

  9. 【数据结构与算法】哈希算法的原理和应用详解!

    在程序员的实际开发中,哈希算法常常能用得到,本文以哈希算法的原理和应用为核心,和大家详细讲解一下哈希算法的概念.常见算法以及原理.在信息安全的应用等等. 一.概念 哈希表就是一种以 键-值(key-i ...

最新文章

  1. 201621123069 《Java程序设计》第十一周学习总结
  2. 我们曾探讨过的微信功能
  3. Geoserver怎样设置地图shp文件为相对路径,可轻松复制移植
  4. scm maven_在运行时访问工件的Maven和SCM版本
  5. 酷6暴力裁员,是清洗也是重塑
  6. 瑞晟蓝牙来电语音软件下载_拥有无数功能的工具箱软件
  7. Microsoft Surface--Bing™ Maps WPF Control
  8. Java字符字符串类
  9. 实验2-1-5 将x的平方赋值给y (5 分)
  10. java char 比较,为什么我在Java中使用char和int进行比较?
  11. java session时间_java设置session过期时间的实现方法
  12. java 返回进度条_Java中的命令行进度条
  13. 有关sim800l的资料
  14. iOS开发 ----- 加载动画之牛顿摆的实现
  15. 关键点检测——无监督
  16. 第三方直播SDK对比|直播SDK如何选型
  17. 快慢指针的概念及其应用
  18. 《Python深度学习》第一部分读书笔记
  19. 【数据处理】Python,matplotlib 如何画柱状图?如何画各种类型的柱状图?柱子宽度设置;设置X轴刻度用label显示;设置柱子距离x轴的高度;设置柱体颜色;设置柱体描边;并列、多条柱状图
  20. 一个40岁老码农的总结,奋斗没有意义,选择大于努力

热门文章

  1. html css文字标题特效,CSS 实现漂亮的大标题效果
  2. C语言入门——《明解C语言》入门篇第四章练习
  3. 顶尖电子秤ls6恢复出厂_顶尖电子称怎么恢复出厂默认?
  4. SpringBoot整合Activiti7
  5. js视频背景切换js特效代码
  6. STM32学习(窗口看门狗)
  7. 计算机应用计算题(61),计算机应用模拟试题及答案
  8. bytedance怎么读_我被字节的HR骗了...
  9. 国际互联网计算与物联网大会ICOMP 2017高度赞誉DroiBaaS全栈式优化架构
  10. 2011年30家最能赚钱移动互联公司排行榜