11-散列4 Hashing - Hard Version(30 分)

本文介绍了一种基于散列表的逆向问题解决方法——通过已知散列表状态重构输入序列。利用拓扑排序原理,结合线性探测解决冲突,实现最小数优先选择策略,最终完成输入序列的重建。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
	
	 

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值