PAT甲题题解-1078. Hashing (25)-hash散列
二次方探测解决冲突
一开始理解错了,难怪一直WA。
先寻找key%TSize的index处,如果冲突,那么依此寻找
(key+j*j)%TSize的位置,j=1~TSize-1
如果都没有空位,则输出'-'
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstdio> #include <algorithm> #include <string.h> #include <cmath> using namespace std; const int maxn=10200; //之前设置的是10005,然后比10000大的第一个素数是10007 int isprime[maxn]; int prime[maxn]; int cnt=0; int hashing[maxn]; //hash表 /* 素数筛选法,筛选出素数,在存储 然后用二分查找,用来查找比MSize大的最小的素数 */ void init(){ for(int i=0;i<maxn;i++) isprime[i]=1; isprime[1]=0; for(int i=2;i<maxn;i++){ if(isprime[i]){ for(int j=i*2;j<maxn;j+=i) isprime[j]=0; } } for(int i=2;i<maxn;i++){ if(isprime[i]){ prime[cnt++]=i; //printf("%d\n",i); } } } /* 从素数中找出比给定的MSize大的最小素数 */ int binarySearch(int val){ int l=0,r=cnt-1,mid; while(l<r-1){ mid=(l+r)>>1; if(val<=prime[mid]) r=mid; else l=mid; } return prime[r]; } int main() { int m,n,TSize; init(); scanf("%d %d",&m,&n); if(m==1) m=2; //如果m=1,则二分查找出来的是3,所以先要处理下 if(!isprime[m]){ TSize=binarySearch(m); } else TSize=m; //printf("%d\n",TSize); int a[maxn]; memset(hashing,0,sizeof(hashing)); int pos,key; for(int i=0;i<n;i++){ scanf("%d",&key); pos=-1; int idx; for(int j=0;j<TSize;j++){ idx=(key+j*j)%TSize; if(!hashing[idx]){ hashing[idx]=1; pos=idx; break; } } if(i==0){ printf("%d",pos); } else{ if(pos==-1) printf(" -"); else printf(" %d",pos); } } return 0; }