美文网首页
散列表查找

散列表查找

作者: E术家 | 来源:发表于2020-05-19 12:03 被阅读0次
散列技术是记录存储位置和它的关键字之间建立一个确定的对应关系f,使得每个关键字key对应一个存储位置f(key).查找时,根据这个对应关系找到给定值key的映射f(key),若查找集合中存在这个记录,则必定在f(key)的位置上.
  • 适合简单,均匀的数据
  • 不适合大范围查找
直接定值法

根据一定的线性公式对要存储的数据进行映射,比如映射关系:f(k) = a*key + b(a、b为常数)

数字分析法

对于一组数字,选择不易重复的数字作为散列的地址,如手机号的后四位

平方取中法

对于一组数字平方后取所得数据的中间几位数字作为散列地址

折叠法

将关键字从左到右分割成为数相等几部分,然后将这几部分叠加求和,并按散列表长取后几位作为散列地址


折叠法
除留余数法

将要存储的数字除以一个数,求得余数即为散列地址,公式为:f(key) = key mod p (p<=m)
容易导致散列冲突(散列是一种哈希)

随机数法

f(key) = random(key)

处理散列冲突方法

开放定址法

就是一旦发生了冲突,就去寻找下一个空的散列地址,只有散列表足够大,空的散列地址总能找到,并将记录存入


开放定址法公式

公式并非唯一,这里只是一种思路!

再散列函数
再散列函数

当一个函数的结果地址冲突时,使用另一个函数来求地址

链地址法

公共溢出法

如果散列表分部不均匀,会浪费空间资源

代码实现

int main(int argc, const char * argv[]) {
    int arr[HASHSIZE]={12,67,56,16,25,37,22,29,15,47,48,34};
    int i,p,key,result;
    HashTable H;
    
    //1.初始化散列表
    InitHashTable(&H);
    
    //2.向散列表中插入数据
    for(i=0;i<m;i++)
        InsertHash(&H,arr[i]);
    
    //3.在散列表查找key=39
    key=39;
    result=SearchHash(H,key,&p);
    if (result)
        printf("查找 %d 的地址为:%d \n",key,p);
    else
        printf("查找 %d 失败。\n",key);
    
    //4.将数组中的key,打印出所有在散列表的存储地址
    for(i=0;i<m;i++)
    {
        key=arr[i];
        SearchHash(H,key,&p);
        printf("查找 %d 的地址为:%d \n",key,p);
    }

    return 0;
}
//定义散列表长为数组的长度
#define HASHSIZE 12
#define NULLKEY -32768

typedef struct
{
    //数据元素存储基址,动态分配数组
    int *elem;
    //当前数据元素个数
    int count;
}HashTable;
int m=0; /* 散列表表长,全局变量 */

//1.初始化散列表
Status InitHashTable(HashTable *H) {
    int i;
    
    //① 设置H.count初始值; 并且开辟m个空间
    m=HASHSIZE;
    H->count=m;
    H->elem=(int *)malloc(m*sizeof(int));
    
    //② 为H.elem[i] 动态数组中的数据置空(-32768)
    for(i=0;i<m;i++)
        H->elem[i]=NULLKEY;
    
    return OK;
}

//2. 散列函数
int Hash(int key)
{
    //除留余数法
    return key % m;
}

//3. 插入关键字进散列表
void InsertHash(HashTable *H,int key)
{
    
    
    //① 求散列地址
    int addr = Hash(key);
    
    //② 如果不为空,则冲突
    while (H->elem[addr] != NULLKEY)
    {
        //开放定址法的线性探测
        addr = (addr+1) % m;
    }
    
    //③ 直到有空位后插入关键字
    H->elem[addr] = key;
}

//4. 散列表查找关键字
Status SearchHash(HashTable H,int key,int *addr) {
    //① 求散列地址
    *addr = Hash(key);
    
    //② 如果不为空,则冲突
    while(H.elem[*addr] != key)
    {
        //③ 开放定址法的线性探测
        *addr = (*addr+1) % m;
        
        //④H.elem[*addr] 等于初始值或者循环有回到了原点.则表示关键字不存在;
        if (H.elem[*addr] == NULLKEY || *addr == Hash(key))
            //则说明关键字不存在
            return UNSUCCESS;
    }
    
    return SUCCESS;
}

相关文章

  • 查找(散列表)

    定义 散列表通过算术操作将键转化为数组的索引来访问数组中的键值对。散列表的查找算法分两步: 用散列函数将被查找的键...

  • 散列表查找

    散列技术   散列技术的方法指的是不同于顺序查找、二分查找、二叉排序树及B-树上的查找。它不以关键字的比较为基本操...

  • 散列表查找

    之前我说过一些查找的算法,而本文中,也将继续讲述一下关于散列表的查找的一些方法的介绍。 首先了解一下散列技术: 散...

  • 查找-散列表

    1. 描述 思路:通过查找关键字不需要比较就可获得需要的记录的存储位置。这就是一种新的存储技术——散列技术。存储位...

  • 散列表查找

    散列技术是记录存储位置和它的关键字之间建立一个确定的对应关系f,使得每个关键字key对应一个存储位置f(key)....

  • 查找算法

    三种查找算法:顺序查找,二分法查找(折半查找),分块查找,散列表

  • 复习散列表

    本文的学习是通过:现代魔法学院——散列表 1. 散列表 散列表区分于顺序表,顺序表的查找是依次遍历查询,而散列表是...

  • 查找算法-散列表

    当存储记录时,通过散列函数计算出记录的散列地址 当查找记录时,我们通过同样的是散列函数计算记录的散列地址,并按此散...

  • 哈希表查找概述

    0.前言 本节内容如下:1.散列表查找定义2.散列函数的构造方法3.处理散列冲突的方法4.散列表查找算法实现5.S...

  • 数据结构与算法-散列表查找实现

    散列表查找算法实现 首先是需要定义一个散列表的结构以及一些相关的常数。其中HashTable就是散列表结构。结构当...

网友评论

      本文标题:散列表查找

      本文链接:https://www.haomeiwen.com/subject/iulpohtx.html