Пример реализации хэш-таблицы с закрытым хэшированием

 

hash_table_closed_impl.cpp

 

#include "hash_table.hpp"

#include <cassert>

 

struct HashTable

{

structElement

{

intm_key;

intm_value;

enum{ NOT_OCCUPIED, OCCUPIED, DELETED } m_status;

};

 

intm_tableSize;

intm_numOccupied;

Element* m_pData;

};

 

// Функция создания новой хэш-таблицы

HashTable* HashTableCreate ( int_initialSize )

{

HashTable * pNewHT = newHashTable;

 

pNewHT->m_tableSize = _initialSize;

pNewHT->m_pData = newHashTable::Element[ pNewHT->m_tableSize ];

 

HashTableClear( * pNewHT );

 

returnpNewHT;

}

 

// Функция уничтожения хэш-таблицы

voidHashTableDestroy ( HashTable* _pHT )

{

delete[] _pHT->m_pData;

delete_pHT;

}

 

// Функция очистки хэш-таблицы

voidHashTableClear ( HashTable & _ht )

{

_ht.m_numOccupied = 0;

for( inti = 0; i < _ht.m_tableSize; i++ )

_ht.m_pData[ i ].m_status = HashTable::Element::NOT_OCCUPIED;

}

 

// Функция получения количества хранимых пар ключ-значение

intHashTableNumElements ( constHashTable & _ht )

{

return_ht.m_numOccupied;

}

 

// Функция вычисления хэш-кода для ключа - для чисел может быть такой тривиальной.

// Для других типов ключей в подобной функции следует реализовать подходящую логику.

unsigned intHashCode ( int_key )

{

unsigned inthashCode = _key;

returnhashCode;

}

 

// Вспомогательная функция для вставки пары ключ-значение в конкретную ячейку хэш-таблицы

boolHashTableTryInsertElement ( HashTable & _ht, int_bucketNr, int_key, int_value )

{

if( _ht.m_pData[ _bucketNr ].m_status != HashTable::Element::OCCUPIED )

{

_ht.m_pData[ _bucketNr ].m_status = HashTable::Element::OCCUPIED;

_ht.m_pData[ _bucketNr ].m_key = _key;

_ht.m_pData[ _bucketNr ].m_value = _value;

_ht.m_numOccupied++;

return true;

}

else if( _ht.m_pData[ _bucketNr ].m_key == _key )

{

_ht.m_pData[ _bucketNr ].m_value = _value;

return true;

}

Else

return false;

}

 

// Функция удвоения размера хэш-таблицы с повторным хэшированием

voidHashTableDoubleSize ( HashTable & _ht )

{

intoldSize = _ht.m_tableSize;

_ht.m_tableSize <<= 1;

 

HashTable::Element* oldData = _ht.m_pData;

_ht.m_pData = newHashTable::Element[ _ht.m_tableSize ];

for( inti = 0; i < _ht.m_tableSize; i++ )

_ht.m_pData[ i ].m_status = HashTable::Element::NOT_OCCUPIED;

_ht.m_numOccupied = 0;

 

for( inti = 0; i < oldSize; i++ )

if( oldData[ i ].m_status == HashTable::Element::OCCUPIED )

HashTableInsert( _ht, oldData[ i ].m_key, oldData[ i ].m_value );

 

delete[] oldData;

}

 

// Функция вставки новой пары ключ-значение в хэш-таблицу

void HashTableInsert ( HashTable & _ht, int_key, int_value )

{

if( ( _ht.m_numOccupied << 1 ) >= _ht.m_tableSize )

HashTableDoubleSize( _ht );

 

unsigned inthashCode = HashCode( _key );

intbucketNr = hashCode % _ht.m_tableSize;

 

for( inti = bucketNr; i < _ht.m_tableSize; i++ )

if( HashTableTryInsertElement( _ht, i, _key, _value ) )

return;

 

for( inti = 0; i < bucketNr; i++ )

if( HashTableTryInsertElement( _ht, i, _key, _value ) )

return;

}

 

// Функция получения значения из хэш-таблицы по ключу

intHashTableGet ( constHashTable & _ht, int_key )

{

unsigned inthashCode = HashCode( _key );

intbucketNr = hashCode % _ht.m_tableSize;

 

for( inti = bucketNr; i < _ht.m_tableSize; i++ )

if( _ht.m_pData[ i ].m_status == HashTable::Element::NOT_OCCUPIED )

break;

else if ( _ht.m_pData[ i ].m_status == HashTable::Element::OCCUPIED &&

_ht.m_pData[ i ].m_key == _key )

return_ht.m_pData[ i ].m_value;

 

for( inti = 0; i < bucketNr; i++ )

if( _ht.m_pData[ i ].m_status == HashTable::Element::NOT_OCCUPIED )

break;

else if( _ht.m_pData[ i ].m_status == HashTable::Element::OCCUPIED &&

_ht.m_pData[ i ].m_key == _key )

return_ht.m_pData[ i ].m_value;

 

return-1;

}

 

// Функция удаления пары ключ-значение из хэш-таблицы по ключу

voidHashTableRemoveKey ( HashTable & _ht, int_key )

{

unsigned inthashCode = HashCode( _key );

intbucketNr = hashCode % _ht.m_tableSize;

 

for( inti = bucketNr; i < _ht.m_tableSize; i++ )

if( _ht.m_pData[ i ].m_status == HashTable::Element::OCCUPIED &&

_ht.m_pData[ i ].m_key == _key )

{

_ht.m_pData[ i ].m_status = HashTable::Element::DELETED;

--_ht.m_numOccupied;

return;

}

 

for( inti = 0; i < bucketNr; i++ )

if( _ht.m_pData[ i ].m_status == HashTable::Element::OCCUPIED &&

_ht.m_pData[ i ].m_key == _key )

{

_ht.m_pData[ i ].m_status = HashTable::Element::DELETED;

--_ht.m_numOccupied;

return;

}

 

assert( !"key not found" );

}

 








Дата добавления: 2016-01-29; просмотров: 735;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.019 сек.