11-散列4 Hashing - Hard Version(30 分)
Given a hash table of size N, we can define a hash function . 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
#include<stdio.h>
#include<stdlib.h>
typedef struct NODE *PtrN;
struct NODE
{
int data;
int inde;
};
typedef struct QUE* PtrQ;
struct QUE
{
int* que;
int front;
int rear;
int size;
};
typedef struct LNODE *PtrL;
struct LNODE
{
int index;
PtrL Next;
};
PtrQ CreateQue(int N)
{
PtrQ Que = (PtrQ)malloc(sizeof(struct QUE));
Que->que = (int*)malloc(sizeof(int)*N);
Que->front = 0;
Que->rear = 0;
Que->size = N;
return Que;
}
int Isempty(PtrQ Que)
{
if (Que->front == Que->rear)
return 1;
else return 0;
}
void Enque(PtrQ Que, int temp)
{
if ((Que->rear + 1) % Que->size == Que->front)return;
Que->rear = (Que->rear + 1) % Que->size;
Que->que[Que->rear] = temp;
return;
}
int DeQue(PtrQ Que)
{
if (Isempty(Que))return -1;
else
{
Que->front = (Que->front + 1) % Que->size;
//printf("%d ", Que->que[Que->front]);
return Que->que[Que->front];
}
}
void InsertLink(PtrL head, int i)
{
while (head->Next != NULL)head = head->Next;
head->Next = (PtrL)malloc(sizeof(struct LNODE));
head = head->Next;
head->index = i;
head->Next = NULL;
return;
}
int Findmin(PtrN List, int N)
{
int i, min, index;
//PtrN minP;
min = 1000000;
index = -1;
for (i = 0; i < N; i++)
{
if (List[i].inde == 0 & List[i].data < min)
{
index = i;
min = List[i].data;
}
}
List[index].inde = -1;
return index;
}
int Find(PtrL head,PtrN List)
{
PtrL minP;
PtrL last,minlast;
PtrL tmp;
int min = 100000,index=-1;
last = head;
tmp = head->Next;
while (tmp != NULL)
{
if (List[tmp->index].data < min)
{
min = List[tmp->index].data;
minP = tmp;
minlast = last;
index = tmp->index;
}
tmp = tmp->Next;
last = last->Next;
}
minlast->Next = minP->Next;
free(minP);
return index;
}
int main()
{
FILE *fp;
fp = fopen("Text.txt", "r");
int N;
fscanf(fp, "%d", &N);
PtrN List = (PtrN)malloc(sizeof(struct NODE)*N);
PtrL Link=(PtrL)malloc(sizeof(struct LNODE)*N);
int i, j, temp;
PtrQ Que;
Que = CreateQue(N);
/*录入数据,初始化Link*/
for (i = 0; i < N; i++)
{
fscanf(fp, "%d", &List[i].data);
List[i].inde = -1;
Link[i].index = -1;
Link[i].Next = NULL;
}
/*计算入度,创建邻接表*/
for (i = 0; i < N; i++)
{
if (List[i].data != -1)
{
j = List[i].data%N;
if (j == i)
List[i].inde = 0;
else
{
temp = j;
while (temp != i)
{
List[i].inde++;
InsertLink(&Link[temp],i);
temp = (temp + 1) % N;
}
List[i].inde++;
}
}
}
/*top排序算法*/
while (1)
{
temp = Findmin(List,N);
if (temp < 0)
break;
Enque(Que, temp);
while (!Isempty(Que))
{
i = DeQue(Que);
printf("%d ", List[i].data);
while (Link[i].Next != NULL)
{
j = Find(&Link[i],List);
List[j].inde--;
if (List[j].inde == 0)
{
Enque(Que, j);
List[j].inde = -1;/*访问过的标记*/
}
}
}
}
/*while (!Isempty(Que))
{
i=DeQue(Que);
printf("%d ", List[i].data);
}*/
printf("\n");
getchar();
return 0;
}