Hash(散列函数)_哈希函数_EncodedStar的博客-程序员资料

技术标签: 算法总结  C语言  学习笔记  

概念
Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。
常用HASH函数
直接取余法:f(x):= x mod maxM ; maxM一般是不太接近 2^t 的一个质数。
乘法取整法:f(x):=trunc((x/maxX)*maxlongit) mod maxM,主要用于实数。
平方取中法:f(x):=(x*x div 1000 ) mod 1000000); 平方后取中间的,每位包含信息比较多。
处理冲突方法
1.开放寻址法;Hi=(H(key) + di) MOD m,i=1,2,…,k(k<=m-1),其中H(key)为散列函数,m为散列表长,di为增量序列,可有下列三种取法:
1). di=1,2,3,…,m-1,称线性探测再散列;
2). di=1^2,(-1)^2,2^2,(-2)^2,(3)^2,…,±(k)^2,(k<=m/2)称二次探测再散列;
3). di=伪随机数序列,称伪随机探测再散列。
2. 再散列法:Hi=RHi(key),i=1,2,…,k RHi均是不同的散列函数,即在同义词产生地址冲突时计算另一个散列函数地址,直到冲突不再发生,这种方法不易产生“聚集”,但增加了计算时间。
3. 链地址法(拉链法)
4. 建立一个公共溢出区
通过查找关键字不需要比较就可以获得需要的记录的存储位置,在记录存储位置和它的关键字之间建立一个确定的关系使得每一个关键对应一个存储位置,查找时,根据这个确定的关系来找到对应的值。记录我们存取的这块空间就是我们所说的表(哈希表)。
优点:
查找简化了比较过程,效率大大的提高。
缺点:
需要找到合适的对应关系,同一种对应关系不一定适合二种情况,移植性不强。而且必须考虑到不同的值对应统一关键字处理。
构造函数
1.计算简单
计算复杂的算法会消耗大量的时间,也会降低效率,这样就不会体现出它本身查找速度快的优点了。
2.2.散列地址均匀
保证空间的有效利用,减少为处理冲突而消耗的时间。
总结:
散列表是一种非常高效的查找数据结构,在原理上也与前面的查找不尽相同,它回避了关键字直接反复比较的繁琐。应该说,散列表对于那种查找性能要求比较高的,记录之间关系无要求的数据有非常好的适用性。在学习中要注意的是散列函数的选择和处理冲突的方法。

简单的对冲突进行处理,代码如下:

#include <stdio.h>
#include <stdlib.h>
#include<stdlib.h>
#define SUCCESS 1
#define UNSUCCESS 0
#define HASHSIZE 12
#define NULLKEY -32768
#define OK 1
typedef struct
{
    int *elem;
    int count;

}HashTable;
int m = 12;
//初始化散列表
void InitHashTable(HashTable *H)
{
    int i;
    m = HASHSIZE;
    H->elem = (int *)malloc(m * sizeof(int) );
    for(i = 0; i < m; i++)
        H->elem[i] = NULLKEY;
//  return 0;
}
//散列函数
int Hash(int key)
{
    return key % m;
}
//插入关键字进散列表
void InsertHash(HashTable *H, int key)
{
    int addr = Hash(key); //求散列地址
    int di = rand();
    while(H->elem[addr] != NULLKEY)
        addr = (addr + di) % m;
    H->elem[addr] = key;
}
//散列表查找关键字
bool SearchHash(HashTable H, int key, int *addr)
{
    *addr = Hash(key);
    while(H.elem[*addr] != key)
    {
        *addr = (*addr + 1) % m;
        if(H.elem[*addr] == NULLKEY || *addr == Hash(key))
        {
            return UNSUCCESS;
        }
    }
    return SUCCESS;
}

HashTable hash;

int main()
{
    int addr;
    InitHashTable(&hash);
    InsertHash(&hash,25);
    InsertHash(&hash,37);
    InsertHash(&hash,15);
    InsertHash(&hash,16);
    InsertHash(&hash,48);
    InsertHash(&hash,67);
    InsertHash(&hash,56);
    InsertHash(&hash,22);
    InsertHash(&hash,47);
    printf("%d\n",SearchHash(hash,223,&addr));
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Code_star_one/article/details/70049737

智能推荐

用乐鑫国内镜像构建ESP8266_RTOS_SDK开发环境_乐鑫sdk镜像_晨之清风的博客-程序员资料

陈拓 2021/01/28-2021/01/281. 概述在《Win10-Ubuntu子系统构建ESP8266_RTOS_SDK开发环境》https://zhuanlan.zhihu.com/p/346072018https://blog.csdn.net/chentuo2000/article/details/112973413?spm=1001.2014.3001.5501一文中我们用github仓库构建了ESP8266开发环境。在从github上克隆ESP8266_RTOS_S

WPS Linux版的公式自动编号且右对齐的方法_linux wps 公式_YUYUYUR的博客-程序员资料

由于Mathtype和AxMath在Linux下用不了,所以,在使用WPS linux版编辑公式时,自动编号和右对齐就无法通过插件完成。手动编号有些麻烦,Latex公式编辑器倒是个好的工具,但是一般不搞研究、不写论文的童靴们用的比较少,因此,在这里,我就介绍一下我的傻瓜式经验。工具:WPS linux版。方法:打开WPS word,建立一个***一行两列***的表格,并调整一下两列的间距,如下图所示;然后,在表格第一列中插入公式:插入-公式;接着,在表格第二列中插入公式编号:引用-

css制作俄罗斯方块,H5原创俄罗斯方块(基于canvas)_xianghao huang的博客-程序员资料

第一次写俄罗斯方块的时候已经是1年多前了,也是我刚刚学js不久。为了加强对js的理解又加上对游戏的爱好,于是在没有参考他人的思路和代码下,自己用最基本的js代码写出了基于canvas的俄罗斯方块。在大三的暑假,我又用了es6的语法进行了改进,包含了class的语法糖、箭头函数等,进一步增加自己对es6的理解,代码有400+行想要做这个小游戏,必须先熟悉H5的canvas,js对数组的处理,键盘事件...

软件测试书籍有哪些_软件测试书籍推荐_测试开发书籍_hhl18的博客-程序员资料

软件测试行业在国内才起步不久,很多人都是刚刚毕业就进入这个行业,或者从其他岗位转过来,对软件测试的知识和技能了解的有限,而软件测试又是一个非常重视实践经验的工作。如何在较短时间内熟悉软件测试的基础知识、并掌握一定的软件测试基本方法,读书就是一个比较好的办法。  因此小编整理了几本软件测试方面的书籍,本文首先介绍了软件测试书籍三步曲,分别是基础知识类、进阶类以及自动化测试的书籍,最...

The server time zone value ‘Öйú±ê׼ʱ¼ä‘ is unrecognized_the server time zone value '脰脨鹿煤卤锚脳录脢卤录盲' is unrec_你认识小汐吗的博客-程序员资料

问题:springboot启动过程中,数据库报错:The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more原因:SYSTEM为SQL默认美国时间,而我们中国要比他们迟8小时,因此将时区设置为当前系统时区即可,采用+8:00格式解决办法:登录mysql数据库,执行如下命令:...

疯狂的程序员-第二十五章_iteye_13777的博客-程序员资料

说那男生,个子不高,其貌不扬,说话声音极小,样子老实本分,问他:“会C++吗?”还便真老老实实地回答:“不会,我会VB。”总之怎么看怎么像块踏踏实实做技术的材料。再说那女生,问她:“会C++吗?”她答:“我编程的水平在这个城市应该是数一数二的,怎么不会C++。”这真是语不惊人死不休吓了绝影一跳,想自己在这学校里呆了四年,论写程序的水平,自我感觉还不错,至少在学校里没有他看得上的人,听了这女...

随便推点

Windows11/10 使用RDP远程桌面时提示 您的凭据不工作/登录没有成功可能的一种原因-程序员资料

目录看本文之前请先看问题解决看本文之前请先看微软官方的关于有关远程桌面客户端的常见问题问题Windows新装系统时就已经设置了Windows Hello,而登录系统时一直使用Windows Hello,未使用过密码进行登录能确定登录所用用户名和密码正确新建的本地账户可以正常使用RDP进行远程登录我在使用RDP登录时虽然输入了正确的账号和密码,但是一直提示 您的凭据不工作这种和账号密码错误时一样的提示.网上的方案和官方的解决方法试了一遍,均无法解决,最后发现新建的本地账户能正常使用RDP连接

Bug--找不到依赖包:Could not find com.android.support.constraint:constraint-layout:1.0.1_边道的博客-程序员资料

找不到依赖包:如下所示:Could not find com.android.support.constraint:constraint-layout:1.0.1解决:在工具栏选择 Tools --> Android --> SDK Manager》SDK Tools,勾上show package details,然后把1.0.1勾上,点击OK即可自动下载

串口服务器的作用是什么?-程序员资料

串口服务器提供串口转互联网作用,可以将RS-232/485/422串口转化成TCP/IP网络接口,保持RS-232/485/422串口与TCP/IP网络接口的统计数据双向透明传输。促使串口设备可以马上具有TCP/IP网络接口作用,网络连接开展数据通讯,巨大的拓展串口设备的通讯间距。许多传统的设备如POS、ATM、刷卡机、读卡器、交换机、加油机、RTU、数控机床、测试仪表等不具备联网功能,只具备RS-232/RS-485/RS-422/RS-232/RS-485等串行接口。主要实现以太网和各种窗口之间

Linux主机下配置Oracle 10G开机时自动启动服务_liyf155的博客-程序员资料

在Linux上安装了Oracle 10G,不像Windows系统会创建服务程序,并开机时自动启动相关的Oracle应用服务,所以Linux下需要手动去配置。步骤如下:一、使用root用户修改/etc/oratab 文件:$ gedit /etc/orataborcl:/Oracle/app/product/10.2.0/db_1:N改为:orcl:/Oracle/...

java jpanel 叠加,如何在Java中堆叠/覆盖jPanel?_whatis真实的博客-程序员资料

I am really new to GUI programming in Java, I did a lot of research and I couldn't find an answer to this problem.I have a simple JFrame with a menu, and inside this JFrame I have a JPanel with a log ...

过滤器不过滤某些地址实例_藏红的博客-程序员资料

过滤器不过滤某些地址实例 的一个实例

推荐文章

热门文章

相关标签