导航:首页 > 解决方法 > 散列表中解决冲突的两种方法是

散列表中解决冲突的两种方法是

发布时间:2022-01-08 00:05:10

① 散列表的查找效率主要取决于建表时所选取的散列函数和处理冲突的方法

散列表的查找效益主要取决于建表示所选的散列函数和储蓄方式的这段换成这个是写三角函数的处理方法。

② 关于散列表,散列函数的两个问题。

散列表是一种数据结构,通过散列函数(也就是 hash 函数)将输入映射到一个数字,一般用映射出的数字作为存储位置的索引。数组在查找时效率很高,但是插入和删除却很低。而链表刚好反过来。设计合理的散列函数可以集成链表和数组的优点,在查找、插入、删除时实现 O(1) 的效率。散列表的存储结构使用的也是数组加链表。执行效率对比可以看下图 1.3:

散列表的主要特点:

  1. 将输入映射到数字

③ 有一个表长为m的散列表,初始状态为空,现将n(n<m)个不同的关键码插入到散列表中,解决冲突的方法是用线

假设n个关键码的散列值均为x,那么:
插入第一个关键码时,检查x位置,结果为空,直接插入,探测次数为0;
插入第二个关键码时,检查x位置,结果不为空,采用线性探测法,继续探测x+1位置,结果为空,插入,探测次数为1;
……
插入第n个关键码时,x位置不为空,从x+1位置开始探测,直至探测到x+(n-1)位置时才为空(这里假设x+(n-1)<m),执行插入操作,探测次数为n-1次。
所以,总的探测次数是一个等差数列,首项为0,公差为1,项数为n,那么,总次数自然可以用等差数列的求和公式算出,即S=a1+n*(n-1)*b/2=0+n*(n-1)*1/2=n(n-1)/2。

④ 已知散列表长度为13,散列函数为H(key)=key % 11,处理冲突的方法为线性探测法

10%11=10 a[9]=10

8%11=8 a[7]=8

40%11=7 a[6]=40

27%11=5 a[4]=27

21%11=10

57%11=2 a[1]=57

46%11=2

23%11=1 a[0]=23

19%11=8

56%11=1

21和10冲突 且a[10]空 所以a[10]=21

46和57冲突 且a[2]空 所以 a[2]=46

19和8冲突 且a[8]空 所以 a[8]=19

56和23冲突 且a[1]、a[2]不空,a[3]空 a[3]=56

最后是23,57,46,56,27,空,40,8,19,10,21,空,空

查找成功的平均长度:6*1+3*2+1*3=15

查找不成功的平均长度:6+5+4+3+2+1+6+5+4+3+2+1=42

(4)散列表中解决冲突的两种方法是扩展阅读:

直接寻址法

例如:有一个从1到100岁的人口数字统计表,其中,年龄作为关键字,哈希函数取关键字自身。

数字分析法

有学生的生日数据如下:

年.月.日

75.10.03

75.11.23

76.03.02

76.07.12

75.04.21

76.02.15

经分析,第一位,第二位,第三位重复的可能性大,取这三位造成冲突的机会增加,所以尽量不取前三位,取后三位比较好。

平方取中法

取关键字平方后的中间几位为哈希地址。

折叠法

将关键字分割成位数相同的几部分(最后一部分的位数可以不同),然后取这几部分的叠加和(舍去进位)作为哈希地址,这方法称为折叠法。

例如:每一种西文图书都有一个国际标准图书编号,它是一个10位的十进制数字,若要以它作关键字建立一个哈希表,当馆藏书种类不到10,000时,可采用此法构造一个四位数的哈希函数。

除留余数法

取关键字被某个不大于哈希表表长m的数p除后所得余数为哈希地址。

H(key)=key MOD p (p<=m)

随机数法

选择一个随机函数,取关键字的随机函数值为它的哈希地址,即

H(key)=random(key),其中random为随机函数。通常用于关键字长度不等时采用此法。

若已知哈希函数及冲突处理方法,哈希表的建立步骤如下:

Step1.取出一个数据元素的关键字key,计算其在哈希表中的存储地址D=H(key)。若存储地址为D的存储空间还没有被占用,则将该数据元素存入;否则发生冲突,执行Step2。

Step2.根据规定的冲突处理方法,计算关键字为key的数据元素之下一个存储地址。若该存储地址的存储空间没有被占用,则存入;否则继续执行Step2,直到找出一个存储空间没有被占用的存储地址为止。

⑤ 散列表处理冲突的二次探测法,表长要求是满足4j+3的质数。但我在做题过程中发现有的表长不满足这一条

合理误差

⑥ 哈希查找的解决冲突

影响哈希查找效率的一个重要因素是哈希函数本身。当两个不同的数据元素的哈希值相同时,就会发生冲突。为减少发生冲突的可能性,哈希函数应该将数据尽可能分散地映射到哈希表的每一个表项中。解决冲突的方法有以下两种:
(1) 开放地址法
如果两个数据元素的哈希值相同,则在哈希表中为后插入的数据元素另外选择一个表项。
当程序查找哈希表时,如果没有在第一个对应的哈希表项中找到符合查找要求的数据元素,程序就会继续往后查找,直到找到一个符合查找要求的数据元素,或者遇到一个空的表项。
(2) 链地址法
将哈希值相同的数据元素存放在一个链表中,在查找哈希表的过程中,当查找到这个链表时,必须采用线性查找方法。
例3. 6是一个简单的哈希查找算法程序,你可以将它和本章结尾的有关代码一起编译连接成一个可执行程序。
例3.6一个简单的哈希查找算法程序
1: #include<stdlib.h>
2: #include<string.h>
3: #include list.h
4: #include hash.h
5:
6: #define HASH_SIZE 1024
7:
8: static listnode_t *hashTable[HASH_SIZE];
9:
10: void insert(const char * s)
11: {
12: listnode_t *ele = newNode((void * ) s)
13: unsigned int h = hash(s) % HASH_SIZE;
14:
15: ele->next = hashTable[h]
16: hashTable[h] = ele;
17: }
18:
19: void print (void)
20: {
21: int h;
22:
23: for (h = 0; h < HASH_SIZE; h++)
24: {
25: listnode_t * lp = hashTalbe[h];
26:
27: if(lp == NULL)
28: continue;
29: printf([%d] , h);
30: while (lp)
31: {
32: printf( '%s' , lp->u.str)
33: lp = ip->next;
34: }
35: putchar (' ');
36: }
37: }
38:
39: const char *search(const char *s)
40: {
39: unsigned int h = hash(s) % HASH_SIZE;
42: listnode_t * lp = hashTable[h];
43:
44: while (lp)
45: {
46: if (! strcmp (s, lp->u.str))
47: return lp->u.str;
48: lp = lp->next;
49: }
50: return NULL;
51: }
请参见:
3. 4 哪一种查找方法最方便?
3.5 哪一种查找方法最快?
3.8 怎样查找链表中的数据?
_____________________________________________
以下是一个简单示例:
#include<iostream>
#include<string>
using namespace std;
#define m 5 //人数
#define n 10 //哈希表长度
#define q 7 //随机数
struct name{
char *py;
int k;
};
name namelist[n];
struct hash{
char *py;
int k;
int s;
};
hash hashlist[n];
void listname()
{
char *f;
int s0,r,i;
namelist[0].py=as;
namelist[1].py=sa;
namelist[2].py=d;
namelist[3].py=f;
namelist[4].py=g;
for(i=0;i<m;i++)
{
s0=0;
f=namelist[i].py;
for(r=0;*(f+r)!='';r++)
s0+=*(f+r);
namelist[i].k=s0;
}
}
void creathash()
{
int i;
for(i=0;i<n;i++)
{
hashlist[i].py=;
hashlist[i].k=0;
hashlist[i].s=0;
}
for(i=0;i<m;i++)
{
int sum=0;
int adr=(namelist[i].k)%q;
int d=adr;
if(hashlist[adr].s==0)
{
hashlist[adr].py=namelist[i].py;
hashlist[adr].k=namelist[i].k;
hashlist[adr].s=1;
}
else
{
while(hashlist[d].k!=0)
{
d=(d+namelist[i].k%5+1)%q;
sum+=1;
}
hashlist[d].py=namelist[i].py;
hashlist[d].k=namelist[i].k;
hashlist[d].s=sum+1;
}
}
}
void find()
{
string nam;
int s0=0,r,sum=1,adr,d;
cout<<请输入姓名的拼音:<<endl;
cin>>nam;;
for(r=0;r<20;r++)
s0+=nam[r];
adr=s0%q;
d=adr;
if(hashlist[adr].k==s0)
cout<<姓名:<<hashlist[d].py<< <<关键字:<<s0<< <<查找长度为: 1<<endl;
else if(hashlist[adr].k==0)
cout<<无此记录!<<endl;
else
{
int g=0;
while(g==0)
{
d=(d+s0%5+1)%q;
sum+=1;
if(hashlist[d].k==0)
{
cout<<无此记录!<<endl;
g=1;
}
if(hashlist[d].k==s0)
{
cout<<姓名:<<hashlist[d].py<< <<关键字:<<s0<< <<查找长度为: 1<<endl;
g=1;
}
}
}
}
void display()
{
int i;
float av=0;
for(i=0;i<n;i++)
{
cout<<姓名:<<hashlist[i].py<< <<关键字:<<hashlist[i].k<<搜索长度:<<hashlist[i].s<<endl;
}
for(i=0;i<7;i++)
{
av+=hashlist[i].s;
}
av/=m;
cout<<平均查找长度:=<<av<<endl;
}
int main()
{
char x;
listname();
creathash();
cout<<d. 显示哈希表 f. 查找 任意键退出 请选择:<<endl;
while(cin>>x){
if(x=='d'){display(); cout<<endl;}
else if(x=='f'){find();cout<<endl;}
else break;
}
return 0;
}

⑦ 散列查找的处理冲突的方法

思路:从发生冲突的那个单元开始,按照一定次序,从散列表中查找出一个空闲的存储单元,把发生冲突的待插入元素存入到该单元的一类处理冲突的方法。
在使用该方法处理冲突的散列表中,查找一个元素的过程是:先根据给定关键字K,利用与插入时使用的同一散列函数h(K)计算出散列地址(设下标为d),然后用K同d单元的关键字比较,若相等则查找成功,否则按插入时处理冲突的相同次序,依次用K同所查单元的关键字比较,直到查找成功或查找到一空单元(表明查找失败)为止。
有三种常见的开放寻址法
(1)线性探查法
是用开放寻址法处理冲突的一种最简单的探查方法。
从发生冲突的d单元起,依次探查下一个单元,直到碰到一个空闲单元或探查完所有单元为止探查时,当达到下标为m-1的表尾单元时,下一个探查的单元是下标为0的表首单元。
探查序列为d,d+1,d+2……,表示为(d+i)%m (0≤i≤m-1)。
例如:构取m=13,线性表为A=(18,75,60,43,54,90,46),构造的散列表如下: 0 1 2 3 4 5 6 7 8 9 10 11 12 H 54 43 18 46 60 75 90 现向表中再插入关键字为31和58的两个元素,用线性探查法解决冲突。
先插入31,h(31)=31%13=5,因H[5]被占用,探查下一个即下标为6的单元,空闲,插入31。 0 1 2 3 4 5 6 7 8 9 10 11 12 H 54 43 18 31 46 60 75 90 再插入58,h(58)=58%13=6,因H[6]被占用,探查下一个即下标为7的单元,因H[7]仍不空闲,再接着向下探查,当探查到下标为9的单元时,空闲,插入58。 0 1 2 3 4 5 6 7 8 9 10 11 12 H 54 43 18 31 46 60 58 75 90 利用线性探查法处理冲突易造成元素的“堆积”(聚集) 0 1 2 3 4 5 6 7 8 9 10 11 12 H 54 43 18 46 60 75 90 向散列表中插入一个元素:
int Insert (hashlist1 HT,int m,ElemType item)
{
//向长度为m的散列表HT中插入一个元素
int d=H(item.key,m); //可选一种合适的构造散列函数的方法,计算散列地址
int temp=d;
while(HT[d].key != NullTag)
{
//当d单元不空时继续向后查找空位置
d=(d+1)%m;
if(d==temp) return 0;
}
HT[d]=item; //将新元素插入到下标为d的位置
return 1;
}
从散列表中查找一个元素:
int Search (hashlist1 HT,int m, ElemType item)
{
//从长度为m的散列表HT中查找
int d=H(item.key, m);
int temp=d;
while(HT[d].key!=NullTag)
{
//当散列地址中的关键字域不为空则循环
if(HT[d].key==item.key) return d;
else d=(d+1)%m;
if(d==temp) return -1;
}
return -1;
}
(2)平方探查法
探查序列为d,d+1,d+2……,表示为(d+i2)%m(0≤i≤m-1)。递推公式为:
优点:它是一种较好的处理冲突的方法,可以较好避免堆积现象
缺点:不能探查到散列表上所有单元。
例:当d0=5,m=17时,只能探查到下标依次为5、6、9、14、4、13、7、3、1的单元。
d0=5;
d1=(5 +2*1-1)%17=6; d2=(6 +2*2-1)%17=9;
d3=(9 +2*3-1)%17=14; d4=(14 +2*4-1)%17=4;
d5=(4 +2*5-1)%17=13; d6=(13 +2*6-1)%17=7;
d7=(7 +2*7-1)%17=3; d8=(3 +2*8-1)%17=1; d9=(1 +2*9-1)%17=1;
(3)双散列函数探查法
思路:
该方法使用两个散列函数h1和h2,其中h1和前面的h(K)一样,以关键字为自变量,产生一个0~m-1之间的数作散列地址;h2也以关键字为自变量,产生一个1~m-1之间的、并和m互素的数作散列地址。它的探查序列为:
利用双散列法,按一定的距离,跳跃式地寻找“下一个”桶,减少了“堆积”的机会,最多经过m-1次探查,它会遍历表中所有位置,回到H0 位置。
例:给出一组表项关键码{22,41,53,46,30,13,01,67}。散列表为HT[0..10],m = 11。
散列函数为:
Hash(x)=(3x) % 11
再散列函数为:
ReHash(x) = (7x) % 10 +1
Hi = ( Hi-1 + (7x) % 10 +1 ) % 11, i = 1, 2,
H0(22) = 0 H0(41) = 2 H0(53) = 5 H0(46) = 6
H0(30) = 2 冲突H1 = (2+1) = 3 ,H0(13) = 6 冲突H1 = (6+2) = 8
H0(01) = 3 冲突H1 = (3+8) = 0 ,H2 = (0+8) = 8 H3 = (8+8) = 5
H4 =(5+8)=2 H5 =(2+8)=10,H0(67)=3 冲突, H1 = (3+10) = 2 H2 = (2+10) = 1
搜索成功的平均搜索长度:
链接法
思路:就是把发生冲突的同义词元素(结点)用单链表链接起来的方法。
例:假定一个线性表B为:B=(18,75,60,43,54,90,46,31,58,73,15,34)。
设采用的散列函数为h(K)=K%13,采用链接法处理:
在该例中,查找成功时平均查找长度为:
ASL=(8×1+3×2+1×3)/12≈1.42
若线性探查法处理冲突进行散列存储,得到:
查找成功时平均查找长度为:
ASL=(7×1+1×2+1×4+1×4+1×2+1×6)/12≈2.1
多种方法分析
在散列表的插入和查找算法中,平均查找长度与表的大小m无关,只与选取的散列函数、α值和处理冲突的方法有关,若假定所选取的散列函数能够使任一关键字等概率地映射到散列空间的任一地址上,理论上证明:
当采用线性探查法处理冲突时,ASL=
当采用链地址法处理冲突时,ASL=
当采用平方探查法、双散列函数法处理冲突时,ASL=
散列存储优缺点
插入与查找的速度相当快根据关键字计算散列地址需要开销一定计算时间占用存储空间较多在散列表中只能按关键字查找元素线性表中元素的逻辑关系无法在散列表中体现。 链表地址法为散列表的每个表象建立一个单链表,用于链接同义词表,为此需要给每个表项增加一个指针域。
关于同义词表的建立,有两种方法。一种方法是在散列表的基本存储区域外开辟一个新的区域用于存储同义词表,这种方法称为“分离的同义词子表法”,或称“独立链表地址法”,这个分离的同义词子表所在的区域称为“溢出区”。另一种方法是不建立溢出区,而是将同义词子表存储在散列表所在的基本存储区域里,例如,可以再基本存储区域里从后向前探测空闲表项,找到后就将其链接到同义词子表中,这个方法称为“结合的同义词子表法”,或称为“公共链表地址法”。
独立链表地址法是查找效率最好的解决冲突的方法,速度要快于开放地址法,因为独立链表地址法在进行散列查找时仅需搜索同义词表。开放地址法要求表长时固定的,而地理链表法中的表项则是动态分配的,其表长仅受内存空间的限制。链表法的主要缺点是需要为每个表项(包括分离的同义子表的每个节点)设立一个指针域。
总之,独立链表地址法的动态结构使它成为散列法中解决冲突的首选方法。

⑧ 简述闭散列表解决冲突的基本思想

动机冲突的基本类型:
勒温按趋避行为将动机冲突分为四大基本类型:
1.双趋冲突
指两种对个体都具有吸引力的目标同时出现,形成强度相同的二个动机。由于条件限制,只能选其中的一个目标,此时个体往往会表现出难于取舍的矛盾心理,这就是双趋冲突。“鱼与熊掌不可兼得”就是双趋冲突的真实写照。
2.双避冲突
指两种对个体都具有威胁性的目标同时出现,使个体对这两个目标均产生逃避动机,但由于条件和环境的限制,也只能选择其中的一个目标,这种选择时的心理冲突称之为双避冲突。“前遇大河,后有追兵”正是这种处境的表现。
3. 趋避冲突
指某一事物对个体具有利与弊的双重意义时,会使人产生二种动机态度:一方面好而趋之,另一方面则恶而远之。所谓“想吃鱼又怕鱼刺”就是这种冲突的表现。
动机冲突可以造成个体不平衡、不协调的心理状态,严重的心理冲突或持续时间较长可以引起个体的心理障碍,对求美者更要注意一点。
4. 多重趋避
在实际生活中,人们的趋避冲突常常表现出一种更复杂的形式,即人们面对着两个或两个以上的目标,而每个目标又分别具有吸引和排斥两方面的作用。人们无法简单的选择一个目标,而回避或拒绝另一个目标,必须进行多重的选择。由此引起的冲突叫作多重趋避冲突。

阅读全文

与散列表中解决冲突的两种方法是相关的资料

热点内容
压缩机拆铜方法视频 浏览:308
国标食品毒理学试验方法有哪些 浏览:820
赶猴子的最佳方法 浏览:846
音乐气息交叉解决方法 浏览:66
阿诗丹顿热水器使用方法 浏览:551
三菱fx27plc指令解决方法 浏览:774
blum五金安装方法 浏览:740
火腿配红酒食用方法 浏览:31
企业前景分析方法 浏览:919
治疗压力强迫症的方法 浏览:56
模仿小罐茶的最佳方法 浏览:916
按部就班的分析方法 浏览:9
中耳炎的治疗方法是怎样的 浏览:759
有效学习方法应该具备什么条件 浏览:443
九阳c91t的使用方法 浏览:645
幼儿手工折衣服衬衫的方法视频 浏览:364
折衣服的方法视频教程 浏览:654
钢筋盖的厚度计算方法 浏览:397
直发剂使用方法 浏览:37
狸窝的使用方法 浏览:778