# 不用拓补排序 不用求偏移量——11-散列4 Hashing - Hard Version

### 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.

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.

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.

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int outtimes=0, psn = 0,flag = 1;//将来可能会在递归中用到的计数器
void print(vector<struct node> &v, vector<int> &h, int n, vector<int> v1);
struct node {//对于每个数，需要知道它的大小和状态（-1不能放入或尚未尝试到，1是已输出，并且找到了位置）
int data;
int status;
};
int hashing(int x,int p)//找位置需要
{
return x%p;
}
bool cmp(const struct node &n1, const struct node &n2)
{
return n1.data < n2.data;
}
int find(const vector<int> &vv1, const int &x)//对于已建好的和未见好的hash表来说，可用同一个函数来寻找它们的位置
{
int cnum=1,pos = hashing(x, vv1.size());
int pos1=pos;
while (vv1[pos] >= 0&&vv1[pos]!=x)
{
pos = (pos1 + cnum) % vv1.size();//不是一般的加减加减的情况
cnum++;
}
return pos;
}
int main(void)
{
vector<int> v1,h;
vector<struct node> v2;
int n, pos, x,pos1;
struct node y;
cin >> n;
for (int i = 0; i < n; i++)//有些复杂的输入（构造三个容器）
{
cin >> x;
if (x >= 0)//准备在统计将来输出次数（比较low的避免末尾空格的方法）
psn++;
v1.push_back(x);
y.data = x;
y.status = -1;
v2.push_back(y);
h.push_back(-1);
}
sort(v2.begin(), v2.end(), cmp);//将v2中的数据排序好
while(1)
{
print(v2, h, n, v1);
if (flag == 1)//当没有状态为-1的数时，说明输出完成
break;
flag = 1;
}
return 0;
}
void print(vector<struct node> &v, vector<int> &h, int n,vector<int> v1)
{
int pos1,pos;//两个位置，pos在v2中，pos1记录在v1中的位置
for (pos = 0; pos != n; pos++)
{
if (v[pos].data >= 0 && v[pos].status == -1)//不是空的，需要尝试
{
pos1 = find(h, v[pos].data);
flag = -1;//做到这一步说明还有需要输出的，改为-1
if (pos1 == find(v1, v[pos].data))//关键：两者中位置相同
{
h[pos1] = v[pos].data;//同时要更新h中的状态
v[pos].status = 1;
cout << v[pos].data;
if (outtimes < psn - 1)//low的避免空格的方法
cout << ' ';
outtimes++;
print(v, h, pos,v1);//返回找之前是不是有数也可以被输出了
}
else
;//不需要更新-1
}
else
v[pos].status = 1;//即使是空的，也需要更新状态
}
}


（其实在每一遍遍历入度时，就是在尝试将其放入新建hash表）

• 0
点赞
• 0
收藏
觉得还不错? 一键收藏
• 打赏
• 0
评论
11-25 1176
11-25 192
11-25 318
11-23 1550
11-27 1736
11-25 435
11-23 522
11-24 419

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

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

01xx0110xx

¥1 ¥2 ¥4 ¥6 ¥10 ¥20

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