1078 Hashing (25 分)(hash表二次方探查法)

本文介绍了一种使用二次探测法解决哈希表中冲突的算法,通过定义哈希函数为H(key)=key%TSize,并在发生冲突时采用正增量的二次探测法寻找下一个空位。特别地,如果用户定义的表大小不是素数,则会重新定义为下一个最大的素数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

The task of this problem is simple: insert a sequence of distinct positive integers into a hash table, and output the positions of the input numbers. The hash function is defined to be H(key)=key%TSize where TSize is the maximum size of the hash table. Quadratic probing (with positive increments only) is used to solve the collisions.

Note that the table size is better to be prime. If the maximum size given by the user is not prime, you must re-define the table size to be the smallest prime number which is larger than the size given by the user.

Input Specification:

Each input file contains one test case. For each case, the first line contains two positive numbers: MSize (≤10

4

) and N (≤MSize) which are the user-defined table size and the number of input numbers, respectively. Then N distinct positive integers are given in the next line. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print the corresponding positions (index starts from 0) of the input numbers in one line. All the numbers in a line are separated by a space, and there must be no extra space at the end of the line. In case it is impossible to insert the number, print "-" instead.

Sample Input:

4 4

10 6 4 15

Sample Output:

0 1 4 -

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
using namespace std;
int size,n,hashTable[10010];
bool isprime(int num){
    if(num==1) return false;
    for(int i=2;i*i<=num;i++)
        if(num%i==0) return false;
    return true;
}
void insert(int key){
    for(int step=0;step<size;step++){
        int index=(key+step*step)%size;//注意这里不是(key % size + step * step)
        if(hashTable[index]==0){
            hashTable[index]=1;
            cout<<index;
            return;
        }
    }
    cout<<"-";
}
int main()
{
    cin>>size>>n;
    while(!isprime(size)) size++;
    for(int i=0;i<n;i++){
        int key;
        cin>>key;
        if(i) cout<<" ";
        insert(key);
    }
    return 0;
}

 

### 哈希类及其特性和用途 #### 1. 开放寻址法哈希 开放寻址法是一种解决冲突的方法,在这种方法中,所有的元素都存储在哈希数组本身中。当发生碰撞时,算法会在中寻找下一个可用的位置来放置新元素。常见的开放寻址策略包括线性探测、二次探测和双重散列。 - **特性**: 所有的数据项都被存放在哈希内部,不需要额外的空间用于链接节点[^1]。 - **优点**: 高效利用内存资源;由于所有数据都在同一个连续区域,缓存命中率较高。 - **缺点**: 插入删除操作复杂度可能增加到 O(n),特别是在高负载因子下容易形成聚集现象。 - **应用领域**: 当前场景适合于小型固定大小的数据集或者对时间效率要求较高的环境,比如编译器符号实现等。 #### 2. 拉链法 (Separate Chaining) 哈希 拉链法通过维护一个由指针连接起来的列(通常是动态配),用来处理键值映射至同一索引位置的情况。每个桶位实际上是一个指向单向链头部的引用。 - **特性**: 使用外部链接结构保存溢出记录,允许任意数量的条目共享相同的 hash code 而不会破坏整体性能。 - **优点**: 对抗聚类效果好,即使装载因数较大也能保持较好的平均访问速度;易于扩展容量以适应更多输入项目的需求。 - **缺点**: 需要额外开销创建并管理这些附加节点实例;相比紧凑布局更耗费总字节数量级。 - **适用场合**: 数据规模不确定且频繁变动的情况下特别有用,例如网络路由选择中的高速缓冲区设计。 #### 3. Cuckoo Hashing Cuckoo hashing 是一种基于两个独立hash函数构建而成的技术方案。它允许多个key共用相同slot的同时还能保证查找时间为常数级别O(1)- **特点**: 利用了双散列机制使得每次插入最多只需要两次尝试即可找到合适的位置; 如果失败则重新调整整个布直至成功为止. - **优势**: 提供了理论上的最坏情况下的恒定检索成本, 并且具有较低的记忆体占用比例. - **局限性**: 初始化过程较为耗时, 同时对于极端情况下可能出现无限循环的风险也需要特殊手段规避. - **典型运用**: 实现高效的LRU Cache 或者作为布式系统的底层支撑组件. #### 4. Robin Hood Hashing Robin Hood hashing 属于线性探查的一种变种形式,它的核心理念在于尽量减少最长距离差异从而达到更加均匀的整体现状态. - **特征描述**: 记录每一个entry离初始目标槽位的距离差额,并以此为基础决定后续迁移顺序优先级高低. - **积极意义**: 显著改善了标准LP所面临的尾部延迟问题,提升了全局均衡程度. - **潜在缺陷**: 编码难度稍大一点,而且某些特定条件下可能会引发不必要的大规模重组动作. - **现实案例**: Web服务器session跟踪系统里经常采用此类方法论优化用户体验质量. ```python class LinearProbingHashTable: def __init__(self, size=8): self.size = size self.keys = [None]*size self.values = [None]*size def put(self, key, value): index = self.hash_function(key) while self.keys[index]: if self.keys[index]==key: break index=(index+1)%len(self.keys) self.keys[index]=key self.values[index]=value def get(self,key): start_index=self.hash_function(key) position=start_index while True: current_key=self.keys[position] if not current_key or current_key==key: return self.values[position] position+=1 if position>=len(self.keys): position-=len(self.keys) if position==start_index: raise KeyError('Key Not Found') ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小火汁猛猛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值