散列表-开放地址法和链地址法的实现
来源:互联网 发布:用户画像 大数据知乎 编辑:程序博客网 时间:2024/06/15 06:23
基本定义
散列技术是在记录的存储位置和它的关键字之间建立一个确定的对应关系 f,使得每个关键字key对应一个存储位置f(key)。这种对应关系f称为散列或哈希函数。采用上述思想将数据存储在一块连续的存储空间中,这块连续的存储空间称为散列或哈希表。关键字对应的存储位置称为散列地址。散列技术最适合的求解问题是查找与给定值相等的记录。
如果碰到两个不同的关键字
散列函数构造方法
好的散列函数参考如下两个原则:
- 计算简单
- 散列地址分布均匀
最常用的方法是除留余数法,对于散列表长度为m的散列函数是
处理散列冲突
处理散列冲突的常用方法有两种,一种是开放地址法,一种是链地址法。
开放地址法
开放地址法就是一旦发生冲突,就去寻找下一个空的散列地址,只要散列表足够大,空的散列表总能找到,并存入。开放地址法又分为线性探测法,二次探测法和随机探测法。
线性探测法的公式是:
二次探测法目的是为了不让关键字都聚集在某一区域,公式为:
链地址法
将所有同义词的关键字存储在同一个单链表中,称这个单链表为同义词子表,在散列表中只存储同义词子表的头指针。只要有冲突,就在同义词的子表中增加结点。
开放地址的代码实现
#include <stdio.h>#include <stdlib.h>#define MaxSize 100 // 存储空间初始分配大小#define HashSize 12 //哈希表数组的长度#define NULLKEY -32768 //哈希表数组初始值typedef struct{ int *elem ; // 数据元素存储基址,动态分配数组 int count; // 当前元素的个数}HashTable;int m = 0; // 哈希表表长void InitHashTable(HashTable *Hash){ m = HashSize; Hash->count = m; Hash->elem = (int *)malloc(m * sizeof(int)); for(int i = 0; i < m; i++) Hash->elem[i] = NULLKEY;}int Hash_fuction(int key){ return key % m; //除留余数法}void InsertHash(HashTable *Hash, int key){ int addr = Hash_fuction(key); //求哈希地址 //如果不为空,则冲突 while(Hash->elem[addr] != NULLKEY) { addr = (addr + 1) % m; // 开放定址法的线性探测 } Hash->elem[addr] = key;}int SearchHash(HashTable *Hash, int key, int *addr){ int tmp = Hash_fuction(key); *addr = Hash_fuction(key); //如果不相等,则冲突 while(Hash->elem[*addr] != key) { *addr = (*addr + 1) % m; //如果继续查找为空或回到原点,则关键字不存在 if(Hash->elem[*addr] == NULLKEY || *addr == Hash_fuction(key)) return false; } return true;}int main(int argc, char const *argv[]){ int arr[HashSize]={12,67,56,16,25,37,22,29,15,47,48,34}; HashTable Hash; InitHashTable(&Hash); for(int i = 0; i < m; i ++) { InsertHash(&Hash, arr[i]); } int addr; int key = 56; int result = SearchHash(&Hash, key, &addr); if(result) printf("值为%d在哈希表的地址为:%d\n", key, addr); else printf("关键字不存在\n"); key = 10; result = SearchHash(&Hash, key, &addr); if(result) printf("值为%d在哈希表的地址为:%d\n", key, addr); else printf("关键字不存在\n"); for(int i = 0; i < m; i ++) { key = arr[i]; result = SearchHash(&Hash, key, &addr); if(result) printf("值为%d在哈希表的地址为:%d\n", key, addr); else printf("关键字不存在\n"); } return 0;}
运行结果是:
值为56在哈希表的地址为:8关键字不存在值为12在哈希表的地址为:0值为67在哈希表的地址为:7值为56在哈希表的地址为:8值为16在哈希表的地址为:4值为25在哈希表的地址为:1值为37在哈希表的地址为:2值为22在哈希表的地址为:10值为29在哈希表的地址为:5值为15在哈希表的地址为:3值为47在哈希表的地址为:11值为48在哈希表的地址为:6值为34在哈希表的地址为:9
链地址的代码实现
哈希表的C实现(一) - 红心李 - 博客园
http://www.cnblogs.com/xiekeli/archive/2012/01/13/2321207.html
哈希表的C实现(二) - 红心李 - 博客园
http://www.cnblogs.com/xiekeli/archive/2012/01/16/2323391.html
哈希表的C实现(三)—传说中的暴雪版 - 红心李 - 博客园
http://www.cnblogs.com/xiekeli/archive/2012/01/17/2324433.html
哈希表的链地址法实现和哈希桶实现_程式設計
http://lubia.cn/hashing-bucket-implementation
散列表(二):冲突处理的方法之链地址法的实现(哈希查找) - Meditation - 博客频道 - CSDN.NET
http://blog.csdn.net/jnu_simba/article/details/9632675
- 散列表-开放地址法和链地址法的实现
- 散列表-开放地址法
- 开放地址散列表
- 哈希表(HashTable)的开放定址法和链地址法的实现
- 开放地址——平法探测散列表
- 解决哈希表的冲突-开放地址法和链地址法
- 解决哈希表的冲突-开放地址法和链地址法
- 解决哈希表的冲突-开放地址法和链地址法
- 解决哈希表的冲突-开放地址法和链地址法
- 开放地址法与链表法的优缺点及其实现
- 开放地址法
- 开放地址法
- Hash-开放地址法
- 散列表的实现-开放定址法
- 【hash表】两种实现(链地址法,开放地址法)
- 开放地址法无锁哈希表实现
- hash 开放地址法源码
- 链地址散列表
- CentOS一般用户和root用户之间的切换
- StarUML使用说明-指导手册
- 深入理解计算机各种类型大小(sizeof)
- 基于jquery实现的类似百度搜索的输入框自动完成功能
- [c++]通过一个简单的程序引出#define与typedef的区别
- 散列表-开放地址法和链地址法的实现
- java多线程之CountdownLatch简单应用
- 【LeetCode】Remove Nth Node From End of List
- Jsp中EL表达式的使用
- Spring注入Bean的几种方式
- asp.net中使用Uploadify插件实现多张图片上传,上传后可显示缩略图、删除图片
- java中的应用和c++中的指针的区别
- 在secureCRT中创建Button按钮自动执行命令
- 计算机网络原理笔记