hashing-hard version 自己的想法

题目是这样子的:

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

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

没去看讲解前自己想的,大概想法是先把余数和位置的差为0的那些数按从小到大的顺序插进去,再把剩下的数一个个插进去。结果运行超时,而且在Insert_nonzero那里总是段错误,就写到博客里记下来了。

下面是代码:

//思路:先算出每个数除以表长的余数,余数一样的一起处理
//余数一样的,位置越靠后越晚输入
//余数和位置的差很重要!差组成部分应该是:余数相同且差比它小的(记作a)、a与它之间插入的一些... 
//输出方式不止一种的,输出那个最小的 
//最终思路:先将差值为0的从小到大插入链表,然后再将差值不为0的一个个插进去

#include<stdio.h>
#include<stdlib.h>
typedef struct Node *PtrToNode;
typedef PtrToNode List;
struct Node
{
	int Data;//存放数据 
	int Remainder;//每个数除以表长的余数
	int Difference;//位置减余数的差
	PtrToNode Next;//指向下一个结点 
};

//表排序
void TableSort(List HashTable,int Size,int Table_1[],int choice)//choice为1表示按data排序,为2表示按difference排序 
{
	int i,j,temp;
	 
	if(choice==1)//按Data从小到大排
	{
	    //给Table排序 
		for(i=1;i<Size;i++)
	    {
	    	temp=Table_1[i];
	    	for(j=i;j>0&&HashTable[temp].Data<HashTable[Table_1[j-1]].Data;j--)
	    	    Table_1[j]=Table_1[j-1];
	    	Table_1[j]=temp;
	    }
	}
	else if(choice==2)//按Difference从小到大排
	{
	    //给Table排序 
		for(i=1;i<Size;i++)
	    {
	    	temp=Table_1[i];
	    	for(j=i;j>0&&HashTable[temp].Difference<HashTable[Table_1[j-1]].Difference;j--)
	    	    Table_1[j]=Table_1[j-1];
	    	Table_1[j]=temp;	
	    }
	} 
}

void Insert_zero(List Output,List HashTable,int Table_1[],int Zero_Size)
{
	PtrToNode NewCell;
	int i; 
	
	//先把Difference为0的按Data从小到大排序 
	TableSort(HashTable,Zero_Size,Table_1,1);
	
	//插入 
	for(i=Zero_Size-1;i>=0;i--)
	{
		NewCell=(PtrToNode)malloc(sizeof(struct Node));
		NewCell->Data=HashTable[Table_1[i]].Data;
		NewCell->Difference=HashTable[Table_1[i]].Difference;
		NewCell->Remainder=HashTable[Table_1[i]].Remainder;
		//头插
		NewCell->Next=Output->Next;
		Output->Next=NewCell; 
	}
}

//difference已经从小到大排了,直接按顺序一个个插进去就好了 
void Insert_nonzero(List Output,List HashTable,int Table_1[],int Size)
{
	int i,j;
	PtrToNode P_Node=(PtrToNode)malloc(sizeof(struct Node));
	PtrToNode P_OutputNode=Output->Next;
	PtrToNode pre;//用来插入的辅助指针 
	for(i=0;i<Size;i++)
	{
		if(HashTable[Table_1[i]].Difference!=0)
		{
			//找到要插入的位置 
			while(P_OutputNode&&P_OutputNode->Remainder!=HashTable[Table_1[i]].Remainder)
		        P_OutputNode=P_OutputNode->Next;
		    pre=P_OutputNode; 
			j=HashTable[Table_1[i]].Difference-1;
			while(pre&&j>0)
			{
				pre=pre->Next;
				j--;
			}
			//插在pre后 
			HashTable[Table_1[i]].Next=(PtrToNode)malloc(sizeof(struct Node));
			HashTable[Table_1[i]].Next=pre->Next;
			*P_Node=HashTable[Table_1[i]];
			pre->Next=P_Node; 
		}
	}
}

void print_OutputList(List Output)
{
	PtrToNode p=Output->Next;
	while(p)
	{
		printf("%d",p->Data);
		if(p->Next!=NULL)
		    printf(" ");
	}
}


int main()
{
	int N;
	scanf("%d",&N);
	
	//把数据放进表里 
	List HashTable=(List)malloc(N*sizeof(struct Node));//用来存放各个数以及他们的位置和余数 
	int Data,Remainder,Difference;
	int Size=0;//Table的大小 
	int Zero_Size=0;//记录位置与余数差为0的个数 
	int i;
	for(i=0;i<N;i++)
	{
		scanf("%d",&Data);
		if(Data!=-1)
		{
			Size++;
			Remainder=Data%N;
			Difference=i-Remainder;
            if(Difference<0)
                Difference=Difference+N;
			if(Difference==0)
			    Zero_Size++;
			HashTable[Size-1].Data=Data;
			HashTable[Size-1].Difference=Difference;
			HashTable[Size-1].Remainder=Remainder;
		}
	}
	//按difference从小到大排,为后面插入difference非0的项做准备
	//Table_1为表排序对应的Table 
	int *Table_1=(int *)malloc((Size)*sizeof(int)); 
	//初始化Table
	for(i=0;i<Size;i++)
	    Table_1[i]=i;
	TableSort(HashTable,Size,Table_1,2); 
	
	//先将位置减余数的差为0的放进Output,并按Data从小到大排 
	List Output=(List)malloc(sizeof(struct Node));
    Output->Next=NULL;
	Insert_zero(Output,HashTable,Table_1,Zero_Size);
	
	//再把位置减余数的差不为0的插进去
	Insert_nonzero(Output,HashTable,Table_1,Size);
	
	//输出
	print_OutputList(Output);
	
	return 0; 
} 

上一篇:按_1 _2 排序fqlist 递归去空格


下一篇:HTTP流量神器Goreplay核心源码详解