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;
}