数据结构(哈希表查找)

散列表查询数组

  • 散列表技术是在记录的存储位置和它关键字之间创建一个肯定的关系F,使得每一个关键字KEY对应一个存储位置F(KEY)
  • 这里把这种对应关系F称为散列散列函数,又称为哈希函数
  • 采用散列技术将记录存储在一块连续的存储空间中,这块存储空间称为散列表或哈希表。

散列表的查找步骤:dom

  • 当存储记录时,经过散列函数计算出记录的散列地址
  • 当查找记录时,一样经过散列函数计算记录的散列地址,并按此散列地址访问该记录
  • 散列表其实就是用值投影一个地址;直接可经过值查找到记录

构造散列函数的两个基本原则:函数

  计算简单;分布均匀spa

方法:指针

  • 直接定址法:可取关键字某个线性函数的值为散列地址。即 F(key)=a*key+b;(表中数据小且连续)
  • 数分析法:适合处理关键字位数比较大的状况;关键字位数较大,经过数字分析,找出表中每一个数据的不可能重复位做为散列地址(通常为关键字中用来为数据编号的位置)
  • 平方取中法:将关键字平方以后取中间若干位数字做为散列地址(适用于不知道关键字分布,且关键字位数不大的状况)
  • 折叠法:将关键字从左到右分割成位数相等的几个部分,而后将这几部分叠加求和,并按散列表表长取后几位做为散列地址(适用于不知道关键字分布,但知道关键字位数)
  • 除留余数法:对散列表长m的散列函数计算公式:F(key)=key%p(p<=m);p的选择狠关键:最好【接近/等于】m或m的最大质数
  • 随机数法:去关键字的随机数值为他的散列地址。即:F(key)=random(key);(适用于关键字长度不等的状况)

选取方法时可参照的方向:code

  • 计算散列地址所用的时间
  • 关键字长度
  • 散列表大小
  • 关键字分布状况
  • 记录查找的评率

处理散列冲突的方法:blog

  • 开放定址法:一旦发生了冲突,就去寻找下一个空的散列表地址【Fi(key)=(F(key)+Di)%m(Di=1,2,3,...,m-1)】
  • 再散列函数法:一旦发生了冲突,RHi表示多个散列函数,冲突以后就换一个散列函数从新定址【Fi(key)=RHi(key)  (i=1,2,3,...,k)】
  • 链地址法:发生冲突时,利用单链表把数据链在原数的指针上
  • 公共溢出区法:把冲突数据存放在溢出表的一样位置
 1 #define HASESIZE 12
 2 #define NULLKEY -32768
 3 
 4 //利用散列函数获得偏移地址,在数组中对偏移地址存储相应数据达到查找效率为O(1)
 5 typedef struct{
 6     int *elem;//数据元素基址(首地址),动态分配数组;
 7     int count;//当前数据元素个数
 8 }HashTable;
 9 
10 int InitHashTable(HashTable *H){
11     int i;
12     H->count=HASESIZE;
13     H->elem=(int *)malloc(HASESIZE*sizeof(int));
14     if(!H->elem){
15         return -1;
16     }
17     for(i=0;i<HASESIZE;i++){
18         H->elem[i]=NULLKEY;
19     }
20     return 0;
21 }
22 
23 //使用除留余数法
24 int Hash(int key){
25     return key % HASESIZE;
26 }
27 
28 //插入关键字到散列表
29 void InsertHash(HashTable *H,int key){
30     int addr=Hash(key);
31     while(H->elem[addr]!=NULLKEY){//出现冲突
32         addr=(addr+1) % HASESIZE;//开放定址法处理
33         if(addr==Hash(key)){
34             return ;//已近存满
35         }
36     }
37     H->elem[addr]=key;
38 }
39 
40 //散列表查找关键字
41 int SearchHase(HashTable H,int key,int *addr){
42     *addr=Hash(key);
43     while(H.elem[*addr]!=key){
44         *addr=(*addr+1)%HASESIZE;
45         if(H.elem[*addr]==NULLKEY || *addr==Hash(key)){
46             return -1;
47         }
48     }
49     return 0;
50 }
相关文章
相关标签/搜索