typedef int position;
typedef struct HashTbl *HashTable;
struct HashTbl
{
int TableSize;
Cell *TheCells;
}H ;
HashTable InitializeTable( int TableSize )
{
HashTable H;
int i;
if ( TableSize < MinTableSize )
{
Error( "散列表太小" );
return NULL;
}
/* 分配散列表 */
H = (HashTable)malloc( sizeof( struct HashTbl ) );
if ( H == NULL )
FatalError( "空间溢出!!!" );
H->TableSize = NextPrime( TableSize );
/* 分配散列表 Cells */
H->TheCells=(Cell *)malloc(sizeof( Cell )*H->TableSize);
if( H->TheCells == NULL )
FatalError( "空间溢出!!!" );
for( i = 0; i < H->TableSize; i++ )
H->TheCells[ i ].Info = Empty;
return H;
}
Position Find( ElementType Key, HashTable H ) /*平方探测*/
{
Position CurrentPos, NewPos;
int CNum; /* 记录冲突次数 */
CNum = 0;//探索次数是冲突次数加一
NewPos = CurrentPos = Hash( Key, H->TableSize );
while( H->TheCells[ NewPos ].Info != Empty && H->TheCells[ NewPos ].Element != Key )
{
/* 字符串类型的关键词需要 strcmp 函数!! */
if(++CNum % 2)//如果是偶数 、、cnum现在等于1了
{ /* 判断冲突的奇偶次 */
NewPos = CurrentPos + (CNum+1)/2*(CNum+1)/2;
while( NewPos >= H->TableSize )
NewPos -= H->TableSize;
}
else //如果是奇数 ,第二次冲突进入
{
NewPos = CurrentPos - CNum/2 * CNum/2;
while( NewPos < 0 )
NewPos += H->TableSize;
}
}
return NewPos;
}
void Insert( ElementType Key, HashTable H )
{ /* 插入操作 */
Position Pos;
Pos = Find( Key, H );
if( H->TheCells[ Pos ].Info != Legitimate )
{
/* 确认在此插入 */
H->TheCells[ Pos ].Info = Legitimate;
H->TheCells[ Pos ].Element = Key;
/*字符串类型的关键词需要 strcpy 函数!! */
}
}
int main()
{
int TableSize = 10000; /* 散列表的估计大小 */
int wordcount = 0, length;
HashTable H;
ElementType word;
FILE *fp;
char document[30]= "HarryPotter.txt“; /* 要被统计词频的文件名 */
H = InitializeTable( TableSize ); /* 建立散列表 */
if(( fp = fopen(document, "r" ))==NULL)
FatalError("无法打开文件!\n" );
while( !feof( fp ) )
{
length = GetAWord( fp, word ); /* 从文件中读取一个单词 */
if(length > 3)
{ /* 只考虑适当长度的单词 */
wordcount++; /*统计文件中单词总数 */
InsertAndCount( word, H );
}
}
fclose( fp );
printf("该文档共出现 %d 个有效单词,", wordcount);
Show( H ,10.0/100 ); /* 显示词频前10%的所有单词 */
DestroyTable( H ); /* 销毁散列表 */
return 0;
}
应用
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum kindOfEntry{legitimate,empty,deleted};//后面的小标号
typedef unsigned int index;
typedef index position;
typedef int ElementType;
typedef struct hashEntry
{
ElementType element;
enum kindOfEntry info;
int time;
}cell;
typedef struct HashTable
{
int tableSize;
cell *theCells;
}*hashTable;
hashTable initializeTable(int tableSize)
{
hashTable table;
int i;
table=(hashTable)malloc(sizeof(struct HashTable));
table->tableSize=tableSize;//nextPrime(tableSize);
table->theCells=(cell*)malloc(sizeof(cell)*table->tableSize);
for(i=0;i<table->tableSize;i++)
table->theCells[i].info=empty;
return table;
}
int Hash(ElementType key,int tableSize)
{
return key%tableSize;
}
position find(ElementType key,hashTable H)
{
position currentPos;
int collisionNum;
collisionNum=0;
currentPos=Hash(key,H->tableSize);
while(H->theCells[currentPos].info!=empty)//&&H->theCells[currentPos].element!=key//重复数字
{
//平方探测法currentPos += 2 * ++collisionNum-1;
//线性
currentPos++;
if(currentPos>=H->tableSize)
currentPos-=H->tableSize;
collisionNum++;
}
H->theCells[currentPos].time= ++collisionNum;
return currentPos;
}
void insert(ElementType key,hashTable H)
{
position pos;
pos=find(key,H);
if(H->theCells[pos].info!=legitimate)
{
H->theCells[pos].info=legitimate;
H->theCells[pos].element=key;
}
}
int main()
{
int tableSize=10;
double density,ast;
hashTable H;
H=initializeTable(tableSize);
char a[50]={'0'},b[50]={'0'};
scanf("%s",a);
int len = strlen(a),num=0,j=0;
for(int i=0;i<len;i++)
{
if(a[i] != ',')
{
num=num*10+(a[i]-'0');
}
else
{
b[j++]=num;
insert(num,H);
num=0;
}
}
int sum=0;
for(int z=0;z<tableSize;z++)
{
if(H->theCells[z].info != empty)
{
sum=sum+H->theCells[z].time;
}
}
//printf("%d\n",sum);
density= (double)j/(double)tableSize;
ast=(double)sum/(double)j;
printf("%.2lf\n",density);
printf("%.2lf\n",ast);
return 0;
}