7-17 Hashing (25 分)

7-17 Hashing (25 分)

这道题我的思路是,将得到的地址先储存下来,等处理结束后统一处理。
这样做就需要多定义一个数组用来贮存每个数据对应的地址。
而更好的处理方法是只用一个数组储存单当前地址的占用情况,将获得的地址随时输出,不储存。
第一种:

#include <iostream>
#include <algorithm>
#include <climits>
#include <cmath>
using namespace std;
//Hash 输入key,和散列标的大小,得到索引
int Hash(int key,int size){
    return key%size;
}
//输入N,如果当前是素数则返回当前元素,否则返回下一个素数
int NextPrime(int N){ 
    int p,j;
    p = (N%2)?N:N+1;
    if(N == 1 || N == 2) return 2; //note the 1 is not prime,but 2 is prime.
    while(p < 100*N){
        for(j=(int)sqrt(p);j>1;j--)
            if(p%j == 0) break;
        if(j == 1) break;
        else p++;
    }
    return p;
}
// data,一开始存放数据,然后存放地址(addr),index存放地址(addr)对应的key
void Insert(int index[],int data[],int MSize,int N){
    int addr,curraddr,key,p;
    for(int i=0;i<N;i++){
        key = data[i];
        addr = Hash(key,MSize);
        curraddr = addr;
        if(index[curraddr] == -1) data[i] = curraddr;  
        else {
            p = 0; //使用前先初始化
            while(index[curraddr] != -1){
                p++;
                if(p*p >= INT_MAX-1) break; //the p*p don't more than INT_MAX. 
                //Probing must be based on the origin address in every time.
                curraddr = (addr + p*p)%MSize; 
            }
            if(index[curraddr] == -1) data[i] = curraddr;
            else data[i] = -1;
        }
        index[curraddr] = key;
    }
}
int main(){
    int MSize,N,*index,*data;
    scanf("%d%d",&MSize,&N);
    MSize = NextPrime(MSize);

    index = (int*)malloc(sizeof(int)*MSize); //数据的地址
    data = (int*)malloc(sizeof(int)*N); //数据的值

    fill(index, index+MSize,-1);

    for(int i=0;i<N;i++){
        scanf("%d",&data[i]);
    }

    Insert(index,data,MSize,N);

    cout << data[0];
    for(int i=1;i<N;i++){
        if(data[i] != -1) cout << ' ' << data[i];
        else cout << ' ' << '-'; 
    }
    cout << endl;
    
    system("pause");
    return 0;
}

第二种:

#include <iostream>
#include <cmath>
using namespace std;
int MSize,N,book[20000];
int Hash(int key,int size){
    return key%size;
}
int NextPrime(int N){ 
    int p,j;
    p = (N%2)?N:N+1;
    if(N == 1 || N == 2) return 2; //note the 1 is not prime,but 2 is prime.
    while(p < 100*N){
        for(j=(int)sqrt(p);j>1;j--)
            if(p%j == 0) break;
        if(j == 1) break;
        else p++;
    }
    return p;
}
void Insert(int key){
    int addr,curraddr,p;
    addr = Hash(key,MSize);
    curraddr = addr;
    if(book[curraddr] == 0){
        book[curraddr] = 1;
        cout << curraddr;  
    } else {
        p = 0; //使用前先初始化
        while(book[curraddr] != 0){
            if(++p > MSize) break; //the p*p don't more than INT_MAX. 
            //Probing must be based on the origin address in every time.
            curraddr = (addr + p*p)%MSize; 
        }
        if(book[curraddr] == 0) cout << curraddr;
        else cout << '-';
        book[curraddr] = 1;
    }
}
int main(){
    int num;
    scanf("%d%d",&MSize,&N);
    MSize = NextPrime(MSize);
    for(int i=0;i<N;i++){
        scanf("%d",&num);
        if(i != 0) cout << ' ';
        Insert(num);
    }    
    system("pause");
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值