总结【散列,hash】

.散列像用于两组数组的比对,将两个数组的数据散列开,比对查找。数字大的时候,时间复杂度会很高,因此用空间换时间,有三种方法(应用场合):

1.用于判断M数组中的数在N数组中是否出现过:

定义 bool 型 数组 hashTable[Maxn]; //Maxn取数据上限;

(记住)使用前要先初始化,表示初始状态下所有数都没有出现过;

示例:const int Maxn=100010;

           bool hashTable[Maxn]={false};

hashTable[x]=true;//x有出现过;

hashTable[x]=false;//x没有出现过;

自我解读:hashTable数组像一个标记,把读过的每一个数做上记号,等到再次出现时会显示之前的属性(即有没有出现过);

例题:判断M中的数字有没有在N中出现过;

#include <iostream>
using namespace std;
const int Maxn=100;//假设所有数据不超过100;
bool hashTable[Maxn]={false};//表示初始状态下所有数字都没有出现过;
int main()
{
int i,m,n,x;           // m,n谁的数据多无所谓
cout<<"请输入n,m内部元素个数:\n";
cin>>n>>m;
cout<<"请输入n中元素:\n";
for(i=0;i<n;i++)
{
  cin>>x;
  hashTable[x]=true;//标记N中已有的数据x;(读入的时候进行预处理)
}
cout<<"请输入m中元素:\n";
for(i=0;i<m;i++)
{
  cin>>x;
  if(hashTable[x]==false)//注意判断的方法!
  cout<<"NO!\n";
  else cout<<"YES!\n";
}
return 0;
}

时间复杂度为O(N+M);因为只是将两个数组中的元素都扫描了一遍(边输入便记录,吼吼) 

 2.判断M中的每个数在N中出现的次数

定义int 型hashTable[Maxn]; //Maxn取数据上限;

以上两种方法的共性:将输入的元素作为数组下标,来统计这个数的性质;

将查询操作的时间复杂度降到O(1),空间换时间常用法!!

例题:判断M中的每个数在N中出现的次数

#include <iostream>
using namespace std;
const int Maxn=100;//假设所有数据不超过100;
int hashTable[Maxn]={0};//表示初始状态下所有数字都没有出现过;
int main()
{
int i,m,n,x;           // m,n谁的数据多无所谓
cout<<"请输入n,m内部元素个数:\n";
cin>>n>>m;
cout<<"请输入n中元素:\n";
for(i=0;i<n;i++)
{
  cin>>x;
  hashTable[x]++;//标记N中已有的数据x;
}
cout<<"请输入m中元素:\n";
for(i=0;i<m;i++)
{
  cin>>x;
  cout<<"出现次数:";
  cout<<hashTable[x]<<"\n";
}
return 0;
}

(注意输入m的时候,按回车就会传递数据,可以输一个判断一次,也可以整体输,整体判断) 

3.散列(hash):将元素通过一个函数转换为整数,并且用这个元素尽可能唯一的代表这个元素

(1)除留余数法:H(key)=key%mod  ;

将余数作为hash值。若mod为素数,H(key)能尽可能覆盖[0,mod)的每一个数,所以一般取表长为素数,令mod等于表长(!)

若H(key)相同,即有“冲突”,有三种解决方法:

1)线性探查法:即下标为H(key)的位置已被占用,检查H(key)+1的位置,直至有位置,若超过表长还没有位置,就回到表的首位继续循环。

2)平方探查法

3)链地址法

将h(key)相同的key连接成一条链表,于是冲突时,可以通过遍历单链表寻找所有的key.

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

迎风809

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值