91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

HashTable

發布時間:2020-07-20 00:08:37 來源:網絡 閱讀:304 作者:小小小司機 欄目:編程語言

    

   HashTable-散列表/哈希表,是根據關鍵字(key)而直接訪問在內存存儲位置的數據結構。

它通過一個關鍵值的函數將所需的數據映射到表中的位置來訪問數據,這個映射函數叫做散列函數,存放記錄的數組叫做散列表。

   構造哈希表的方法:

     1.直接定址法--取關鍵字的某個線性函數為散列地址,Hash(Key)= Key 或 Hash(Key)= A*Key + B,A、B為常數。

     2.除留余數法--取關鍵值被某個不大于散列表長m的數p除后的所得的余數為散列地址。Hash(Key)= Key % P。

    3.平方取中法

     4.折疊法

     5.隨機數法

     6.數學分析法

  常用方法為直接定址法,除留余數法。

K類型代碼:

#pragma once

#include <string>

enum Status
{
	EXIST,
	DELETE,
	EMPTY,
};

// 仿函數
template<class K>
struct DefaultHashFuncer
{
	size_t operator() (const K& key)
	{
		return key;
	}
};

static size_t BKDRHash(const char * str)
{
	unsigned int seed = 131; // 31 131 1313 13131 131313
	unsigned int hash = 0;
	while (*str )
	{
		hash = hash * seed + (unsigned char)(*str++);
	}
	return (hash & 0x7FFFFFFF);
}

template<>
struct DefaultHashFuncer<string>
{
	size_t operator()(const string& str)
	{
		//size_t value = 0;
		//for (size_t i = 0; i < str.size(); ++i)
		//{
		//	value += str[i];
		//}

		//return value;

		return BKDRHash(str.c_str());
	}
};

template<class K, class HashFuncer = DefaultHashFuncer<K> >
class HashTable
{
public:
	HashTable()
		:_tables(NULL)
		,_status(NULL)
		,_size(0)
		,_capacity(0)
	{}

	HashTable(size_t size)
		:_tables(new K[size])
		,_status(new Status[size])
		,_size(0)
		,_capacity(size)
	{
		//memset(_status, 0, sizeof(Status)*_size);
		for (size_t i = 0; i < _capacity; ++i)
		{
			_status[i] = EMPTY;
		}
	}

	HashTable(const HashTable<K, HashFuncer>& ht)
	{
		HashTable<K, HashFuncer> tmp(ht._capacity);
		for (size_t )
		{}
	}

	HashTable<K, HashFuncer>& operator=(HashTable<K, HashFuncer> ht);

	~HashTable()
	{
		if (_tables)
		{
			delete[] _tables;
			delete[] _status;
		}

		_size = 0;
		_capacity = 0;
	}

	bool Insert(const K& key)
	{
		/*if (_size == _capacity)
		{
			cout<<"Full"<<endl;
			return false;
		}*/

		_CheckCapacity();

		size_t index = _HashFunc(key);
		// 線性探測

		while(_status[index] == EXIST)
		{
			if (_tables[index] == key)
			{
				return false;
			}

			++index;
			if (index == _capacity)
				index = 0;
		}
		
		_status[index] = EXIST;
		_tables[index] = key;
		++_size;

		return true;
	}

	int Find(const K& key)
	{
		int i = 0; 
		size_t index = _HashFunc(key);
		while (_status[index] != EMPTY)
		{
			if (_tables[index] == key
				&& _status[index] != DELETE)
			{
				return index;
			}

			++i;
			index = _HashFunc(key)+i*i;
			++index;
			if (index == _capacity)
			{
				index = 0;
			}
		}

		return -1;
	}

	bool Remove(const K& key)
	{
		int index = Find(key);
		if (index != -1)
		{
			_status[index] = DELETE;
			return true;
		}

		return false;
	}

	void Swap(HashTable<K, HashFuncer>& ht)
	{
		swap(_tables, ht._tables);
		swap(_size, ht._size);
		swap(_status, ht._status);
		swap(_capacity, ht._capacity);
	}

	size_t _HashFunc(const K& key)
	{
		//
		//return key%_capacity;
		HashFuncer hf;
		return hf(key)%_capacity;
	}

	void PrintTables()
	{
		for (size_t i = 0 ; i < _capacity; ++i)
		{
			if (_status[i] == EXIST)
			{
				printf("[%d]:E->", i);
				cout<<_tables[i];
			}
			else if (_status[i] == DELETE)
			{
				printf("[%d]:D->", i);
				cout<<_tables[i];
			}
			else
			{
				printf("[%d]:N", i);
			}

			cout<<endl;
		}
	}

	void _CheckCapacity()
	{
		if (_size*10 >= _capacity*7)
		{
			/*K* tmpTables = new K[2*_capacity];
			K* tmpStatus = new Status[2*_capacity];
			for(size_t i = 0; i < _capacity; ++i)
			{
				if ()
				{
				}
			}*/

			HashTable<K, HashFuncer> tmp(2*_capacity);
			for (size_t i = 0; i < _capacity; ++i)
			{
				if (_status[i] == EXIST)
				{
					tmp.Insert(_tables[i]);
				}
			}

			this->Swap(tmp);
		}
	}


protected:
	K* _tables;
	Status* _status;
	size_t _size;
	size_t _capacity;
};

    a:變量分析:

    1.K類型的數組,用來存儲key。

    2.Status類型的數組,用來標志每一個位置狀態。

    3._size,用于表示有效數據個數。

    4._capacity,容量

    b:難點分析

    1.使用仿函數計算不同類型數據的Key。

    2.處理哈希沖突以及載荷因子。

HashTable


KV類型的代碼

#pragma once
#include <string>

enum Status
{
	EXIST,
	DELETE,
	EMPTY,
};
template<class K, class V>
struct KeyValue
{
	K _key;
	V _value;

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

template<class K>
struct DefaultHashFuncer
{
	size_t operator() (const K& key)
	{
		return key;
	}
};

static size_t BKDRHash(const char * str)
{
	unsigned int seed = 131; // 31 131 1313 13131 131313
	unsigned int hash = 0;
	while (*str )
	{
		hash = hash * seed + (unsigned char)(*str++);
	}
	return (hash & 0x7FFFFFFF);
}

template<>
struct DefaultHashFuncer<string>
{
	size_t operator()(const string& str)
	{
		//size_t value = 0;
		//for (size_t i = 0; i < str.size(); ++i)
		//{
		//	value += str[i];
		//}

		//return value;

		return BKDRHash(str.c_str());
	}
};

template<class K, class V,
 class HashFuncer = DefaultHashFuncer<K> >
class HashTable
{
	typedef  KeyValue<K, V> KV;
public:
	HashTable(size_t size)
		:_tables(new KV[size])
		,_status(new Status[size])
		,_size(0)
		,_capacity(size)
	{
		//memset(_status, 0, sizeof(Status)*_size);
		for (size_t i = 0; i < _capacity; ++i)
		{
			_status[i] = EMPTY;
		}
	}

	~HashTable()
	{
		if (_tables)
		{
			delete[] _tables;
			delete[] _status;
		}

		_size = 0;
		_capacity = 0;
	}

	bool Insert(const K& key, const V& value)
	{
		if (_size == _capacity)
		{
			cout<<"Full"<<endl;
			return false;
		}

		//_CheckCapacity();

		// 二次方探測
		int i = 1;
		size_t index = _HashFunc0(key);
		while(_status[index] == EXIST)
		{
			if (_tables[index]._key == key)
			{
				return false;
			}

			index = _HashFunci(index, i++);
		}
		
		_status[index] = EXIST;
		_tables[index] = KV(key, value);
		++_size;

		return true;
	}

	KV* Find(const K& key);

	size_t _HashFunc0(const K& key)
	{
		HashFuncer hf;
		return hf(key)%_capacity;
	}

	size_t _HashFunci(size_t prevHash, int i)
	{
		return (prevHash + 2*i - 1)%_capacity;
	}

protected:
	KV* _tables;
	Status* _status;
	size_t _size;
	size_t _capacity;
};

同理上面K類型,不同的是_tables的每一個元素是一個KeyValue<K,V>類型的結構體。


處理哈希沖突的閉散列方法

 1.線性探測

  2.二次探測


HashTable

   以上就是本人在學習過程中的一些經驗總結。當然,本人能力有限,難免會有紕漏,希望大家可以指正。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

抚松县| 义马市| 武宁县| 来凤县| 集贤县| 宜昌市| 开远市| 平定县| 嘉禾县| 华阴市| 兴隆县| 仙桃市| 景德镇市| 金川县| 边坝县| 西和县| 盐池县| 西乌| 四川省| 栾川县| 翼城县| 大宁县| 泸水县| 芦溪县| 新兴县| 山阳县| 通山县| 岐山县| 湘阴县| 库尔勒市| 汶上县| 新巴尔虎右旗| 临邑县| 都昌县| 石狮市| 汨罗市| 黄石市| 赣榆县| 泰和县| 通州市| 边坝县|