HashTable的C++实现

hash表的实现

1、分离连接法(separate chaining)
#include<vector>
#include<list>
using namespace std;

template <typename HashedObj>
class HashTable
{
  public:
    explicit HashTable( int size = 101 );

    void makeEmpty( )
    {
        for( int i = 0; i < theLists.size( ); i++ )
            theLists[ i ].clear( );
    }

    bool contains( const HashedObj & x ) const
    {
        const list<HashedObj> & whichList = theLists[ myhash( x ) ];
        return find( whichList.begin( ), whichList.end( ), x ) != whichList.end( );
    }

    bool remove( const HashedObj & x )
    {
        list<HashedObj> & whichList = theLists[ myhash( x ) ];
        list<HashedObj>::iterator itr = find( whichList.begin( ), whichList.end( ), x );
        if( itr == whichList.end( ) )
            return false;
        whichList.erase( itr );
        --currentSize;
        return true;
    }

    bool insert( const HashedObj & x )
    {
        list<HashedObj> & whichList = theLists[ myhash( x ) ];
        if( find( whichList.begin( ), whichList.end( ), x ) != whichList.end( ) )
            return false;
        whichList.push_back( x );
        if( ++currentSize > theLists.size( ) )
            rehash( );
        return true;
    }

  private:
    vector<list<HashedObj> > theLists;   // The array of Lists
    int  currentSize;

    void rehash( )
    {
        vector<list<HashedObj> > oldLists = theLists;

        // Create new double-sized, empty table
        theLists.resize( nextPrime( 2 * theLists.size( ) ) );  //使用2*theLists.size( )以后最接近它的素数
        for( int j = 0; j < theLists.size( ); j++ )
            theLists[ j ].clear( );
        // Copy table over
        currentSize = 0;
        for( int i = 0; i < oldLists.size( ); i++ )
        {
            list<HashedObj>::iterator itr = oldLists[ i ].begin( );
            while( itr != oldLists[ i ].end( ) )
                insert( *itr++ );
        }
    }
    int myhash( const HashedObj & x ) const;
    {
        int hashVal = hash( x );
        hashVal %= theLists.size( );
        if( hashVal < 0 )
            hashVal += theLists.size( );
        return hashVal;
    }
};

// A hash function for sting object
int hash( const string & key, int tableSize)
{
    int hashVal = 0;
    for( int i = 0; i < key.length( ); i++ )
        hashVal = 37 * hashVal + key[ i ];
    hashVal %= tableSize;
    if( hashVal < 0)
        hashVal += tableSize;
    return hashVal;
}


2、使用探测法(probing hash tables)
template <typename HashedObj>
class HashTable
{
  public:
    explicit HashTable( int size = 101 ) : array( size ) )
    { makeEmpty( ); }

    void makeEmpty( )
    {
        currentSize = 0;
        for( int i = 0; i < array.size( ); i++ )
            array[ i ].info = EMPTY;
    }

    bool contains( const HashedObj & x ) const
    { return isActive( findPos( x ) ); }

    bool insert( const HashedObj & x )
    {
        // Insert x as active
        int currentPos = findPos( x );
        if( isActive( currentPos ) )
            return false;
        array[ currentPos ] = HashEntry( x, ACTIVE );
        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 ) { }
    };

    vector<HashEntry> array;
    int currentSize;

    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;
    }

    bool isActive( int currentPos ) const
    { return array[ currentPos ].info == ACTIVE; }

    void rehash( )
    {
        vector<HashEntry> oldArray = array;
        // Create new double-sized, empty table
        array.resize( nextPrime( 2 * oldArray.size( ) ) );
        for( int j = 0; j < array.size( ); j++ )
            array[ j ].info = EMPTY;
        // Copy table over
        currentSize = 0;
        for( int i = 0; i < oldArray.size( ); i++ )
            if( oldArray[ i ].info == ACTIVE )
                insert( oldArray[ i ].element );
    }

    int myhash( const HashedObj & x ) const;
};


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值