哈希表学习总结
2016-04-15 09:37
543 查看
什么是哈希表, 哈希函数, 关键字?
关键字: 用户数据
哈希表(Hash Table): 也叫散列表, 是根据关键码值(Key Value) 直接进行数据访问的数据结构.
哈希函数: 也叫散列函数, 是key和[结果]的一种关系. k = f(k);
哈希表有什么用途?
用于加密算法;
用于数字签名;
用于文件校验.
在实际应用中, 哈希表的查找性能是极好的.
在合理的假设下, 它查找一个元素的平均时间是O(1);
哈希函数的构造方法之除留余数法.
在此方法中, 表长代表所有元素个数, 并不是数组长度.
除留余数法此方法为最常用的构造散列函数方法。
对于散列表长为m的散列函数公式为:
f( key ) = key mod p ( p ≤ m ) (p一般取第一个比m小的质数)
代码如下:
哈希表解决冲突方法之 拉链法(链接法/链地址法)
可以使用单链表或双链表, 双链表更方便删除.
代码如下:
相关结构:
创建hash-table操作(create):
插入操作:
先查看表中是否已经存在此元素, 不存在 插入.
删除操作(delete):
删除操作要注意删除元素在对应的key下的链表中的位置.(分首个/中间/最后一个三种)
勿在浮沙筑高台.
关键字: 用户数据
哈希表(Hash Table): 也叫散列表, 是根据关键码值(Key Value) 直接进行数据访问的数据结构.
哈希函数: 也叫散列函数, 是key和[结果]的一种关系. k = f(k);
哈希表有什么用途?
用于加密算法;
用于数字签名;
用于文件校验.
在实际应用中, 哈希表的查找性能是极好的.
在合理的假设下, 它查找一个元素的平均时间是O(1);
哈希函数的构造方法之除留余数法.
在此方法中, 表长代表所有元素个数, 并不是数组长度.
除留余数法此方法为最常用的构造散列函数方法。
对于散列表长为m的散列函数公式为:
f( key ) = key mod p ( p ≤ m ) (p一般取第一个比m小的质数)
代码如下:
/*======================================================================\ * Author (作者): i.sshe * Date (日期): 2016/03/26 * Others (其他): 寻找<num的最大质数 \*=======================================================================*/ int generate_mod_value(int num) { int i = 0; int j = 0; int temp = 0; int flag = 0; for (i = num; i > 2; i--) { flag = 1; for (j = 2; j <= i/2; j++) { if(i % j == 0) //不是质数 { flag = 0; break; } } if (flag == 1) { temp = i; break; } } // temp = i; if (num < 4) { temp = num; } printf("除留余数法取得的mod值为:%d\n", temp); return temp; }
哈希表解决冲突方法之 拉链法(链接法/链地址法)
可以使用单链表或双链表, 双链表更方便删除.
代码如下:
相关结构:
/*=========================================================================*\ * #struct# * \*=========================================================================*/ typedef struct HASH_NODE_S_ { int data; struct HASH_NODE_S_ *prev; struct HASH_NODE_S_ *next; }HASH_NODE_S; typedef struct HASH_TABLE_S_ { HASH_NODE_S *hash_node; }HASH_TABLE_S;
创建hash-table操作(create):
HASH_TABLE_S *create_hash_table(int len, int num) { HASH_TABLE_S *hash_table = NULL; int i = 0; int tempvalue = 0; hash_table = (HASH_TABLE_S *)malloc(len * sizeof(HASH_TABLE_S)); if (hash_table == NULL) { printf("hash table malloc error!\n"); exit(1); } memset(hash_table, 0, len * sizeof(HASH_TABLE_S)); //还要增加用户输入数据, 重复的需要链接到后面 printf("请输入数据:\n"); for (i = 0; i < num; i++) { scanf("%d", &tempvalue); insert_element(hash_table, len, tempvalue); } return hash_table; }
插入操作:
先查看表中是否已经存在此元素, 不存在 插入.
int insert_element(HASH_TABLE_S *hash_table, int hash_len, int value) { int position_num = value % hash_len; HASH_NODE_S *node ; if (search_element(hash_table, hash_len, value)) { return 0; } node = (HASH_NODE_S *)malloc(sizeof(HASH_NODE_S)); if (node == NULL) { printf("insert element malloc error!\n"); exit(1); } node->data = value; if (hash_table[position_num].hash_node != NULL) //冲突了 { node->next = hash_table[position_num].hash_node; hash_table[position_num].hash_node->prev = node; hash_table[position_num].hash_node = node; node->prev = NULL; } else { hash_table[position_num].hash_node = node; } return 1; }
删除操作(delete):
删除操作要注意删除元素在对应的key下的链表中的位置.(分首个/中间/最后一个三种)
int delete_element(HASH_TABLE_S *hash_table, int mod_value, int value) { HASH_NODE_S *current_node = NULL; int position_key = value % mod_value; current_node = hash_table[position_key].hash_node; while (current_node != NULL) { if (current_node->data == value) { //此元素的第一个元素 if (current_node->prev == NULL && current_node->next != NULL) { hash_table[position_key].hash_node = current_node->next; current_node->next->prev = NULL; } else if (current_node->prev != NULL && current_node->next == NULL) { // 此元素是最后一个元素 current_node->prev->next = NULL; } else if(current_node->prev != NULL && current_node->next != NULL) { //此元素是中间的元素 current_node->prev->next = current_node->next; current_node->next->prev = current_node->prev; } else { //只剩一个元素 hash_table[position_key].hash_node = NULL; } free(current_node); printf("删除成功!\n"); return 1; } current_node = current_node->next; } printf("没有此元素!\n"); return 0; }
勿在浮沙筑高台.
相关文章推荐
- c语言实现hashmap(转载)
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- C#数据结构之顺序表(SeqList)实例详解
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- Lua教程(七):数据结构详解
- Ruby中Hash的11个问题解答
- Windows Powershell使用哈希表
- 探索PowerShell (八) 数组、哈希表(附:复制粘贴技巧)
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- 轻松学习C#的哈希表
- C#数据结构之单链表(LinkList)实例详解
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题