0
点赞
收藏
分享

微信扫一扫

【C++】哈希表 AcWing 840. 模拟散列表 拉链法+开放寻址法(算法基础课笔记)

Ichjns 2022-03-12 阅读 73

目录



在这里插入图片描述

一、题目

1、题目

题目链接{点击跳转}

二、思路

1、知识点

在这里插入图片描述
将任意一个对象传进来或者任何一个数据传进来,然后映射到一个位置int下标index eg、 String
哈希碰撞
在这里插入图片描述
↑拉链法
在这里插入图片描述
时间复杂度 几乎O(1) 除非做的很差or size太小了 导致O(n)
在这里插入图片描述
应用:把较大的数据映射到较小的数
在这里插入图片描述

2、拉链法

在这里插入图片描述
①、插入操作
类似与单链表插入 没做过可以看下 单链表
第一步:创建一个点e[idx] = x
在这里插入图片描述
第二步 创建指针 ne[idx] = h[k]
在这里插入图片描述
第三步:修改指针h[k] = idx++
在这里插入图片描述
②、查询操作
![在这里插入在这里插入图片描述

3、开放寻址法

0x3f3f3f3f的作用:
1 、相当于无穷大
2、不容易溢出
3、方便数组赋值 memset(a,0x3f,sizeof(a))
参考 – 大佬的链接
②思路
在这里插入图片描述

三、AC代码

拉链法

#include <iostream>
#include <cstring>
using namespace std;
const int N = 100003;//+3是为了让n变为质数  减少冲突的概率

int h[N],e[N],ne[N],idx;

//插入 :头插法
void insert (int x) {
    //c++ 负数取模结果还是负数 
    //  根据取值范围  x % N + N必是正数
    //不加(x + N)% N是因为 x可能取值是负数 根据取值范围   加上N可能还是负数
    int k = (x % N + N) % N; //映射
    e[idx] = x; //创建一个点    
    ne[idx] = h[k];  // 修改指  
    h[k] = idx++; //头指针 指向这个点
}

//查询操作
bool find (int x) {
    int k = (x % N + N) % N;  //映射
    for (int i = h[k]; i != -1;i = ne[i]) {
        if (e[i] == x) {
            return true;
        }
    }
    return false;
}

int main () {
    int n;
    cin >> n;

    memset(h, -1, sizeof h);//清空 空指针用-1表示

    while (n --) {
        string op;
        int x;
        cin >> op >> x;
        if (op == "I") {
            insert(x);
        } 
        else {
            if (find(x)) {
                puts("Yes");
            } 
            else {
                puts("No");
            }
        }
    }
    return 0;
}

开放寻址法

#include <iostream>
#include <cstring>
using namespace std;
//开放寻址法一般开 数据范围的 2~3倍  
const int N = 200003;//+3是为了让n变为质数  减少冲突的概率
const int null = 0x3f3f3f3f;
// 0x3f3f3f3f的十进制是1061109567,也就是10^9级别的(和0x7fffffff一个数量级),
// 而一般场合下的数据都是小于10^9的,所以它可以作为无穷大使用而不致出现数据大于无穷大的情形。
int h[N];

int find (int x) {
    int k = (x % N + N) % N;//映射k的下标
    while (h[k] != null && h[k] != x) {
        k++;
        if (k == N) {//到最后一个位置
            k = 0;
        }
    }
    return k;//如果这个位置为空  则返回它的存储位置
}

int main () {
    int n;
    cin >> n;
    memset(h,0x3f, sizeof h);//将数组清空
    while (n --) {
        string op;
        int x;
        cin >> op >> x;
        if (op == "I") {
            h[find(x)] = x; 
        } 
        else {
            if (h[find(x)] == null) {
                puts("No");
            } 
            else {
                puts("Yes");
            }
        }
    }
    return 0;
}

四、总结

结尾:

举报

相关推荐

0 条评论