散列是一种用于常数平均时间执行插入、删除和查找的技术。但是,那些需要元素间任何排序信息的操作将不会得到有效支持。因此,诸如FINDMIN、FINDMAX以及线性时间按排序顺序将整个表进行打印的操作都是散列所不支持的
如果当一个元素被插入时另一个元素已经存在,那么就产生一个冲突,这个冲突需要解决。
如果当一个元素被插入时另一个元素已经存在,那么就产生一个冲突,这个冲突需要解决。
分离链接法:做法是将散列到同一个值得所有元素保留到一个表中。通常是链表。
1:分离链接散列表的类型声明
#ifndef _HashSep_H
struct ListNode;
typedef struct ListNode *Position;
struct HashTbl;
typedef struct HashTbl *HashTable;
HashTable InitializeTable( int TableSize );
void DestroyTable( HashTable H );
Position Find( Element key,HashTable H );
void Insert( Element key, HashTable H );
ElementType Retrieve( Position P );
#endif
struct ListNode
{
ElementType Element;
Postition Next;
};
typedef Position List;
struct HashTbl
{
int TableSize;
List *TheLists;
};
2:初始化
HashTable
InitializeTable( int TableSize )
{
HashTable H;
int i;
if( TableSize < MinTableSize )
{
Error( "Table size too small!" );
return NULL;
}
H=malloc( sizeof( struct HashTbl ) );
if( h == NULL )
FatalError( "Out of space!" );
h->TableSize = NextPrim( TableSize );
H->TheLists = malloc( sizeof( List ) * H->TableSize );
if( H->TheLists == NULL )
FatalError( "Out of space!" );
for( i=0; i<H->TableSize;i++)
{
H->TheLists[ i ] = malloc( sizeof( struct ListNode ) );
if( H->TheLists[ i ] == NULL )
FatalError( "Out of space!" );
else
H->TheLists[ i ] = NULL;
}
return H;
}
3:查找
Position
Find( Element Key,HashTable H )
{
Position P;
List L;
L = H->TheLists[ Hash( Key,H->TableSize ) ];
P = L->Next;
while( P != NULL && P->Element != Key )
P = P->Next;
return P;
}
开放定址法:如果有冲突发生,就要尝试选择另外的单元,知道找到新的单元为止。
1:类型声明
#ifndef _HashSep_H
typedef unsigned int Index;
typedef Index Position;
struct HashTbl;
typedef struct HashTbl *HashTable;
HashTable InitializeTable( int TableSize );
void DestroyTable( HashTable H );
Position Find( Element key,HashTable H );
void Insert( Element key, HashTable H );
ElementType Retrieve( Position P );
HashTable Rehash( HashTable H );
#endif
enum KindOfEntry { Legitimate ,Empty,Deleted };
struct HashEntry
{
ElementType Element;
enum KindOfEntry Info;
};
typedef struct HashEntry Cell;
struct HashTbl
{
int TableSize;
Cell *TheCells;
};
2:初始化
HashTable
InitializeTable( int TableSize )
{
HashTable H;
int i;
if( TableSize < MinTableSize )
{
Error( "Table size too small!" );
return NULL;
}
H = malloc( sizeof( struct HashTbl ) );
if( H == NULL )
FatalError( "Out of space!" );
H->TableSize = NextPrim( TableSize );
H->TheCells = malloc( sizeof( Cell ) * H->TableSize );
if( H->TheCells == NULL )
FatalError( "Out of space!" );
for( i=0; i<H->TableSize;i++)
{
H->TheCells[ i ].Info = Empty;
}
return H;
}
3:Find例程
Position
Find( Element 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;
if( CurrentPos >= H->TableSize )
CurrentPos -= H->TableSize;
}
return CurrentPos;
}
4:插入例程
void
Insert( Element 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;
}
}