MOOC浙大《数据结构》/ PTA-C语言 / 11-散列4 Hashing - Hard Version (30分)

MOOC

Posted by Kenshin on May 15, 2020
本文字符数:英文760字 | 中文2645字

题目描述

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

思路

看了陈越老师的思路是用拓扑排序做,奈何刚开始学,还没复习过什么都不熟悉,想着用自己的方法做一做,提交 ac 了而且貌似效率还不错的样子,所以试着写下自己的第一篇 Blog。

思路是 degree 保存其当前地址减去哈希地址为排在其前面输入哈希表的数的数目,并复制存入 cmpdegree 以便比较,当其前驱值确定并输出(先放入 a[n]数组)后,其 degree 减 1。当 degree 为-1 时表示此值已经确定了在输入序列的位置不用再进行比较。当最后 degree 都为-1 即表示所有哈希表中的值都已确定的输入次序,此时顺序输出 a[k]即可,其中为-1 的值代表原本哈希表中的空位。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <stdio.h>
int main() {
    int n;
    scanf("%d", &n);
    int i, j, num, min, k = 0, cmp;
    int data[n], degree[n], cmpdegree[n], a[n];
    for (i = 0; i < n; i++) {
    //读入输入数据并计算优先级
        scanf("%d", &num);
        data[i] = num;
        degree[i] = (i - num % n + n) % n;
        if (num < 0)
            degree[i] = -1;
        cmpdegree[i] = degree[i];
    }
    while (k < n) {
        min = -1;//最终仍为-1则表示表中除了空位都已经被输出了
        for (i = 0; i < n; i++)
            if (degree[i] == 0)//0表示可以输出了,同时过滤了不能被输出的和已经输出过的数据
                if (min == -1 || data[i] < min)//寻找其中的最小值
                    min = data[i];
        for (i = 0; i < n; i++) //寻找此最小值所在的位置,其实可以在上个循环中新声明一个变量记录i
            if (data[i] == min)
                break;
        for (j = 0; j < n; j++) {
            cmp = (j - i + n) % n;
            if (degree[j] >= 0 && cmp <= cmpdegree[j])//处理优先级
                degree[j]--;
        }
        a[k] = min;//将结果放入数组中最后一起输出
        k++;//k可以同时充当一个标记的作用
    }
    for (k = 0; k < n; k++) {
        if (a[k] == -1)
            break;//读到-1表示后面对应的都是哈希表中的空位
        if (k != 0)
            printf(" ");
        printf("%d", a[k]);
    }
    return 0;
}