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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章