哈希表的实现(开放定址法)

enum Status
{
	EMPTY,
	EXIST,
	DELETE,
};

template<class K, class V>
struct HashTableNode
{
	K _key;
	V _value;
	Status _status;

	HashTableNode(const K& key = K(), const V& value = V())
		:_key(key)
		, _value(value)
		, _status(EMPTY)
	{}
};

template<class K, class V>
class HashTable
{
	typedef HashTableNode<K, V> Node;
public:
	HashTable(size_t capacity = 10)
		:_table(capacity)
		,_size(0)
	{
	}

	bool Insert(const K& key, const V& value)
	{
		//检查负载因子,查看是否需要扩容
		_Check();
		int index = _HashFunc(key);

		while (_table[index]._status != EMPTY)
		{
			++index;
			if (index == _table.size())
			{
				index = 0;
			}
		}

		_table[index]._key = key;
		_table[index]._value = value;
		_table[index]._status = EXIST;
		_size++;
		return true;
	}
	Node* Find(const K& key)
	{
		size_t index = _HashFunc(key);
		//记录第一次查找的下标
		size_t src = index;

		while (_table[index]._status != EMPTY)
		{
			if (_table[index]._key == key)
			{
				if (_table[index]._status != DELETE)
					return &_table[index];
				else
					return NULL;
			}
			++index;

			if (index == _table.size())
				index = 0;

			//避免死循环操作
			if (index == src)
				return NULL;
		}

		return NULL;
	}

	bool Remove(const K& key)
	{
		Node* ret = Find(key);

		if (ret)
		{
			ret->_status = DELETE;
			--_size;
			return true;
		}

		return false;
	}

	void Display()
	{
		for (size_t i = 0; i < _table.size(); i++)
		{
			if (_table[i]._status == DELETE)
				_table[i]._key = 0;

			cout << "[" << i << "] " << _table[i]._key << endl;
		}
		cout << "size = " << _size << endl;
	}
protected:
	size_t _GetNextPrime(int num)
	{
		const int _PrimeSize = 28;
		static const unsigned long _PrimeList[_PrimeSize] =
		{
			53ul, 97ul, 193ul, 389ul, 769ul,
			1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
			49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
			1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
			50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
			1610612741ul, 3221225473ul, 4294967291ul
		};

		for (size_t i = 0; i < _PrimeSize; i++)
		{
			if (_PrimeList[i] >(unsigned long)num)
				return _PrimeList[i];
		}

		return _PrimeList[_PrimeSize - 1];
	}
	void _Check()
	{
		if (_table.size() != 0 && _size * 10 / _table.size() < 7)
			return;

		//负载因子超过或等于0.7,需要进行扩容
		size_t newsize = _GetNextPrime(_table.size());
		HashTable<K, V> hash;
		hash._table.resize(newsize);
		for (size_t i = 0; i < _table.size(); i++)
		{
			if (_table[i]._status == EXIST)
			{
				hash.Insert(_table[i]._key, _table[i]._value);
			}
		}
		this->_Swap(hash);
	}
	void _Swap(HashTable<K, V>& ht)
	{
		_table.swap(ht._table);
		swap(_size, ht._size);
	}
	size_t _HashFunc(int key)
	{
		return key % _table.size();
	}
	
private:
	vector<Node> _table;
	size_t _size;
};

void test()
{
	HashTable<int, int> hs;
	int a[] = { 44,23,46,8,77};
	for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++)
	{
		hs.Insert(a[i], i);
	}
	hs.Display();
	hs.Remove(8);
	hs.Display();

}
int main()
{
	test();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值