11-散列4 Hashing - Hard Version
Given a hash table of size N, we can define a hash function H(x)=x%N. Suppose that the linear probing is used to solve collisions, we can easily obtain the status of the hash table with a given sequence of input numbers.
However, now you are asked to solve the reversed problem: reconstruct the input sequence from the given status of the hash table. Whenever there are multiple choices, the smallest number is always taken.
Input Specification:
Each input file contains one test case. For each test case, the first line contains a positive integer N (≤1000), which is the size of the hash table. The next line contains N integers, separated by a space. A negative integer represents an empty cell in the hash table. It is guaranteed that all the non-negative integers are distinct in the table.
Output Specification:
For each test case, print a line that contains the input sequence, with the numbers separated by a space. Notice that there must be no extra space at the end of each line.
Sample Input:
11
33 1 13 12 34 38 27 22 32 -1 21
Sample Output:
1 13 12 21 33 34 38 27 22 32
分析
逐个遍历当前桶数组中的数。如果当前数是在当前顺序被输入,那么此前输入的数已经被读到,其所在桶置为-1,故当前数到实际地址之间的桶都为空。因此只需检查当前数所在位置到其hash_code对应位置之间是否还存在其他数,若不存在则说明该节点有可能是在当前被输入的。
代码
#include <bits/stdc++.h>
using namespace std;
int ht[2000];
int main(){
int N; cin>>N; int M = N;
for(int i=0; i<N; i++){
cin>>ht[i]; if(ht[i]<0) M--;
}
while(M--){
ht[1999]=10000000; int f=1999; //要取的index
for(int tf=0; tf<N; tf++){
if(ht[tf]>=0){
int hc_tf = ht[tf]%N; int j=tf; int val_num=0;
//j:逆向遍历当前节点到其哈希位置的迭代器
//val_num:该段空间上元素的数目(若只有ht[idx]一个则说明当前数可能在当前顺序被插入)
do{//不能用for循环,至少得检查当前桶,若N=1for循环会直接跳出
if(ht[j]>=0) if(++val_num>1) break;
j=(j+N-1)%N;
}while((j+1)%N!=hc_tf);
if(val_num==1&&ht[tf]<ht[f])
f = tf;
}
}
cout<<ht[f]; if(M) cout<<" "; ht[f]=-1;
}
return 0;
}