哈希表/哈希函数_学习笔记

1.什么是哈希表?

Hash table  哈希表,可以根据键值(key)直接访问内存存储的数据结构。通过计算函数,将所需要查询的数据映射到表中,映射的这个函数哈希函数,存放记录的数组称作哈希表。(哈希表本质就是数组)

数组的查询效率是最高的

2.实现哈希表的两种方法

  • 数组+链表(是解决哈希冲突的一种方法)
  • 数组+二叉树

3.什么是键值key,它是怎么来的

键值key是通过哈希函数处理之后得到的,根据不同的数据特性会采取不同的哈希函数方法来得到键值。(下面的方法是用不同的哈希函数来设定不同的键值key)


直接地址法

//例如年龄和人口数之间的关系,就可以用直接地址法来存储
//例如 10岁的人口数是100, 20岁的人口数是300,30岁的人口数是1000
#include
//hash_func
int hashFun(int key)
{
    int post = key -1;
    return post;
}

//将年龄对应的人口数保存到哈希表中
void saveAgeNum(int* hash_list,int age,int num)
{
    int post = hashFun(age);//调用hsahFun函数得到存储位置
    hash_list[post] = num;//得到post位置之后将数据num存入
}

//查找某个年龄对应的人口数
int getAgeNum(int* hash_list,int age)
{
    int post = hashFun(age); //通过hash函数计算key值
    return hash_list[post]; //通过key值直接访问数组下标,找到数据
}

int main()
{
    int hash_list[140]; //hash 表本质就是数组
    int age;
    int num;
    int i;
    for(i = 0; i<3 ;i++)  //输入数据
    {
        printf("请输入年龄对应的人口数\n");
        scanf("%d%d",&age,&num);
        saveAgeNum(hash_list,age,num);
    }
    for(i = 0; i<3 ;i++)
    {
        printf("请您输入想要查找的年龄\n");
        scanf("%d",&age);
        printf("%d岁的人口数是%d\n",age,getAgeNum(hash_list,age));
    }
    return 0;
}


叠加法

//比如图书馆的条形码
//321512423
//此时的哈希函数改为
#include 

//图书结构体
typedef struct
{
    int number; //条形码
    char name[20]; //图书名    
}book_t;

int hashtFun(int key)  //哈希函数
{
    int post = (key/1000000 + key/1000%1000 + key%1000) % 1000;
    return post;
}

void saveBookInfo(book_t* hash_list,book_t book)
{
    int post = hashFun(book.number); //通过哈希函数计算键值
    hash_List[post] = book;  //在指定的数组位置上插入
}

book_t getBookInfo(book_t* hash_list,int number)  //函数的返回值是书的名字
{
    int post = hashFun(number);
    return hash_list[post];   
}

int main()
{
    int number;
    book_t book;
    book_t temp;
    book_t hash_list[1000];
    int i ;
    for(i = 0; i<3 ;i++)
    {
        printf("请您输入图书的条形码和名字\n");    
        scanf("%d%s",&temp.number,temp.name);
        saveBookInfo(hash_list,temp);
    }
    for(i = 0; i<3 ;i++)
    {
        printf("请您输入要查找的条形码\n");
        scanf("%d",&number);
        book = getBookInfo(hash_list,number);
        printf("%d --- %s\n",book.number,book.name);
    }
    return 0;
}

还有平方取中法,和保留余数法,根本上都是设置不同的哈希函数来达到目的


4.什么是哈希冲突?如何解决哈希冲突

哈希冲突简单来说就是不同的数据他们的键值经过哈希函数操作后是一样的这就产生了冲突。得把数据 “不一样的” 但 键值 “一样的” 都保存在表内。

开放寻址法和拉链法是两种常见的解决哈希冲突的方法

开放寻址法:当存储位置被占用,就以当前位置为基准,查看下一个位置是否为空,以此类推直到找到空为止。

        缺点:每次冲突都要重新查找空位置,计算时间增加。


拉链法:数组中的每一个元素都是结构体指针,如果发生冲突就通过链表将冲入的元素连接起来。

        优点:因为是链表,所以具有链表所具备的优点,处理冲突简单,无堆积现象,链表上的节点都是动态申请的。

        缺点:当节点规模较小时候开放地址法比较节省空间

你可能感兴趣的:(散列表,哈希算法)