【问题描述】采用除留余数法构造散列函数H(key) = key mod p,散列表的表长为m,其中p≤m,采用线性探测法处理冲突(当探测到表的最后一个位置仍无空位时,从表的开始位置重新探测)。现将n(n≤m)个互不相同的正整数a1,…,an依次插入到散列表中,要求输出构成的散列表以及在插入每个数时需要探查的次数。
【输入形式】
第一行:参数p,散列表长m,正整数的数目n,每个数用空格隔开;
第二行:n个正整数a1,…,an,每个数用空格隔开。
【输出形式】
第一行:散列表的地址序列(0 1 … m-1),每个数用空格隔开;
第二行:将n个正整数插入到散列表中的结果,每个数用空格隔开;若某个地址中没有数则填为-1;
第三行:每个数在插入时的探查次数;若某个地址中没有数则探查次数为0。
【样例输入】
13 15 11
26 36 41 38 44 15 68 12 6 51 25
【样例输出】
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
26 25 41 15 68 44 6 -1 -1 -1 36 -1 38 12 51
1 5 1 2 2 1 1 0 0 0 1 0 1 2 3
【样例说明】
先将11个正整数(26,36,41,38,44,15,68,12,6,51,25)依次插入到表长为15的散列表中,插入过程中采用H(key) = key mod 13来计算插入到表中的位置,若插入位置已有其他数,则采用线性探测法解决冲突。
例:在计算最后一个数25应该插入的位置时,25 mod 13 = 12,但地址12/13/14均无空位,则从地址0开始重新探测,直到地址1有空位,则在地址1中插入25。此时由于依次探查过地址12/13/14/0/1,所以探查次数为5。
#include <iostream>
using namespace std;
int main()
{
struct node {
int data;
int count = 0;
node() { data = -1; }
};
int p, m, n;
cin >> p >> m >> n;
node* array = new node[m];
int* a = new int[n];
for (int i = 0; i < n; ++i) {
cin >> a[i];
int pos = a[i] % p;
int initCount = 1;
// collision
while (array[pos].data != -1) {
pos = (pos + 1) % m;
initCount++;
}
array[pos].data = a[i];
array[pos].count = initCount;
}
for (int i = 0; i < m; ++i) {
cout << i << ' ';
}
cout << endl;
for (int i = 0; i < m; ++i) {
cout << array[i].data << ' ';
}
cout << endl;
for (int i = 0; i < m; ++i) {
cout << array[i].count << ' ';
}
delete [] array;
delete [] a;
return 0;
}