【PAT甲级、C++、散列表之二次探测法】1078 Hashing (25分)

晴神宝典上的写法

# include <iostream>
# include <cmath>
# include <vector>
# include <algorithm>
# include <climits>

using namespace std;

bool isPrime(int n)
{
    
    
    if(n == 1)
        return false;
    
    int sq = (int)sqrt(n);
    for(int i=2;i<=sq;++i)
        if(n%i == 0)
            return false;
    return true;
}



int main(void)
{
    
    
    int Tsize, N, val;
    int HASH[10010] = {
    
    0};
    cin >> Tsize >> N;
    
    while(!isPrime(Tsize))
        Tsize++;
    for(int i=0;i<N;++i){
    
    
        cin >> val;             // 要存入哈希表的数据
        int key = val % Tsize;  // 数据在哈希表中的初始键
        
        // 如果初始键的位置未使用
        if(HASH[key] == 0){
    
    
            HASH[key] = val;
            cout << key;
            if(i != N-1) cout << " ";
        }
        // 如果初始键的位置被使用,就使用二次探测法,一直探测步长1 ~ Tsize-1的范围        
        else{
    
    
            int step;  // 二次探测法的步长
            for(step = 1;step<Tsize;++step){
    
    
                key = (val + step*step) % Tsize;  // 二次探测法的冲突处理公式
                if(HASH[key] == 0){
    
    
                    HASH[key] = val;
                    cout << key;
                    if(i != N-1) cout << " ";
                    
                    break;
                }
            }
            // 如果探测找不到位置,说明该数据无法存储在当前哈希表
            if(step >= Tsize){
    
    
                cout << "-";
                if(i != N-1) cout << " ";
            }
        }

    }
        
    
    return 0;
}

因为初始键其实就是步长为0的时候,所以我稍微改进了一下,代码精简了一些

# include <iostream>
# include <cmath>
# include <vector>
# include <algorithm>
# include <climits>

using namespace std;

bool isPrime(int n)
{
    
    
    if(n == 1)
        return false;
    
    int sq = (int)sqrt(n);
    for(int i=2;i<=sq;++i)
        if(n%i == 0)
            return false;
    return true;
}

int main(void)
{
    
    
    int Tsize, N, val, step, key;
    int HASH[10010] = {
    
    0};
    cin >> Tsize >> N;
    
    // TSize不是素数就让他成为比它更大的素数
    while(!isPrime(Tsize))
        Tsize++;
    
    for(int i=0;i<N;++i)
    {
    
    
        cin >> val;  // 要存入哈希表的数据
        
        // 使用二次探测法探测当前数据的映射存储位置
        // 初始键就是步长step为0,所以放在一个for循环处理也没问题
        for(step = 0;step<Tsize;++step){
    
    
            key = (val + step*step) % Tsize;  // 二次探测法的冲突处理公式
            if(HASH[key] == 0){
    
      // 如果当前位置未使用,就存入
                HASH[key] = val;
                cout << key;
                if(i != N-1) cout << " ";
                break;  // 记得break
            }
        }
        
        if(step >= Tsize){
    
      // 如果探测找不到位置,说明该数据无法存储在当前哈希表
            cout << "-";
            if(i != N-1) cout << " ";
        }
    }
        
    
    return 0;
}

猜你喜欢

转载自blog.csdn.net/MYMarcoreus/article/details/110858420