我试图编辑我的哈希表以形成一个双哈希类,但似乎无法正确处理它。
我想知道是否有人有任何见识。有人告诉我,我需要做的就是编辑findPos(),现在我必须使用一种新策略来提供新的探针。
**我做了一些研究,它说在两次探测中,您将使用R-(x mod R),其中R> size,并且素数小于表的大小。那我要做一个新的哈希函数吗?
这是我的代码:
template <typename HashedObj>
class HashTable
{
public:
explicit HashTable( int size = 101 ) : array( nextPrime( size ) )
{ makeEmpty( ); }
bool contains( const HashedObj & x ) const
{
return isActive( findPos( x ) );
}
void makeEmpty( )
{
currentSize = 0;
for( auto & entry : array )
entry.info = EMPTY;
}
bool insert( const HashedObj & x )
{
// Insert x as active
int currentPos = findPos( x );
if( isActive( currentPos ) )
return false;
if( array[ currentPos ].info != DELETED )
++currentSize;
array[ currentPos ].element = x;
array[ currentPos ].info = ACTIVE;
// Rehash;
if( currentSize > array.size( ) / 2 )
rehash( );
return true;
}
bool insert( HashedObj && x )
{
// Insert x as active
int currentPos = findPos( x );
if( isActive( currentPos ) )
return false;
if( array[ currentPos ].info != DELETED )
++currentSize;
array[ currentPos ] = std::move( x );
array[ currentPos ].info = ACTIVE;
// Rehash; see Section 5.5
if( currentSize > array.size( ) / 2 )
rehash( );
return true;
}
bool remove( const HashedObj & x )
{
int currentPos = findPos( x );
if( !isActive( currentPos ) )
return false;
array[ currentPos ].info = DELETED;
return true;
}
enum EntryType { ACTIVE, EMPTY, DELETED };
private:
struct HashEntry
{
HashedObj element;
EntryType info;
HashEntry( const HashedObj & e = HashedObj{ }, EntryType i = EMPTY )
: element{ e }, info{ i } { }
HashEntry( HashedObj && e, EntryType i = EMPTY )
: element{ std::move( e ) }, info{ i } { }
};
vector<HashEntry> array;
int currentSize;
bool isActive( int currentPos ) const
{ return array[ currentPos ].info == ACTIVE; }
int findPos( const HashedObj & x ) const
{
int offset = 1;
int currentPos = myhash( x );
while( array[ currentPos ].info != EMPTY &&
array[ currentPos ].element != x )
{
currentPos += offset; // Compute ith probe
offset += 2;
if( currentPos >= array.size( ) )
currentPos -= array.size( );
}
return currentPos;
}
void rehash( )
{
vector<HashEntry> oldArray = array;
// Create new double-sized, empty table
array.resize( nextPrime( 2 * oldArray.size( ) ) );
for( auto & entry : array )
entry.info = EMPTY;
// Copy table over
currentSize = 0;
for( auto & entry : oldArray )
if( entry.info == ACTIVE )
insert( std::move( entry.element ) );
}
size_t myhash( const HashedObj & x ) const
{
static hash<HashedObj> hf;
return hf( x ) % array.size( );
}
};
最佳答案
我不确定您是否理解代码,但请允许我提出一些意见,认为不应将其视为答案,但是其大小大于允许注释的大小。
如果您使用二次探测,那么我认为在方法findPos()
中您应该将currentPos
推进为currentPos*currentPos % array.size()
。正如我所看到的,当前,您将currentPos
增大一个单位(offset
最初为1),之后增大2单位,之后增大4,依此类推。
可能您正在尝试一种快速的方法来计算二次探针。如果是这种情况,则offset
不应增加2,而应乘以2。那应该是offset *= 2
,但是因为您应该计算碰撞次数,所以应该增加offset
。
也许更简单的方法是:currentPos += 2*offset++ - 1; // fast way of doing quadratic resolution
调整大小是可以的,因为它可以保证该表至少有一半为空,因此可以保证在执行插入操作时搜索可用条目。
祝好运
关于c++ - 双探针哈希表,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33189714/