#pragma once
#include<vector>
#include<string>
template<class K>
struct SetKeyOfT
{
const K& operator()(const K& key) {
return key;
}
};
namespace bit {
using std::vector;
using std::string;
using std::pair;
template<class T>
struct HashNode
{
T _data;
HashNode<T>* _next;
HashNode(const T& data)
:_data(data)
,_next(nullptr)
{
}
};
//前置声明
template<class K, class T, class KeyOfT, class Hash>
class HashTable;
template<class K,class T,class KeyOfT,class Hash>
struct __HashTableIterator
{
typedef __HashTableIterator<K, T, KeyOfT,Hash> Self;
typedef HashTable<K, T, KeyOfT, Hash> HT;
typedef HashNode<T> Node;
Node* _node;
HT* _pht;
__HashTableIterator(Node* node,HT* _pht)
:_node(node)
,_pht(_pht)
{}
T& operator*()
{
return _node->_data;
}
T* operator->()
{
return &(_node->_data);
}
Self operator++() {
if (_node->_next)
_node = _node->_next;
else
{
//如果一个桶走完了,找到下一个桶继续
KeyOfT koft;
size_t i = _pht->HashFunc(koft(_node->_data)) % _pht->_tables.size();
++i;
for (; i < _pht->_tables.size(); i++)
{
Node* cur = _pht->_tables[i];
if (cur)
{
_node = cur;
return *this;
}
}
_node = nullptr;
return *this;
}
}
bool operator!=(const Self& s)
{
return _node != s._node;
}
};
template<class K>
struct _Hash
{
const K& operator()(const K& key)
{
return key;
}
};
//特化
template<>
struct _Hash<string>
{
size_t operator()(const string& key)
{
size_t hash = 0;
for (size_t i = 0; i < key.size(); ++i)
{
hash *= 131;
hash += key[i];
}
return hash;
}
};
template<class K,class T,class KeyOfT,class Hash = _Hash<K>>
class HashTable
{
typedef HashNode<T> Node;
public:
friend struct __HashTableIterator<K, T, KeyOfT, Hash>;
typedef __HashTableIterator<K, T, KeyOfT,Hash> iterator;
iterator begin()
{
for (size_t i = 0; i < _tables.size();i++)
{
if (_tables[i]) {
return iterator(_tables[i],this);
}
}
return end();
}
iterator end()
{
return iterator(nullptr,this);
}
~HashTable()
{
Clear();
}
void Clear()
{
for (size_t i = 0; i < _tables.size(); ++i)
{
Node* cur = _tables[i];
while (cur)
{
Node* next = cur->_next;
delete cur;
cur = next;
}
_tables[i] = nullptr;
}
}
size_t HashFunc(const K& key) {
Hash hash;
return hash(key);
}
size_t GetNextPrime(size_t prime)
{
const int PRIMECOUNT = 28;
static const size_t primeList[PRIMECOUNT] =
{
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 < PRIMECOUNT; ++i)
{
if (primeList[i] > _num)
{
return primeList[i];
}
return primeList[PRIMECOUNT - 1];
}
}
pair<iterator, bool> Insert(const T& data) {
KeyOfT koft;
//如果负载因子等于1,则增容,避免大量的哈希冲突
if (_tables.size() == _num) {
//1.开二倍大小的新表(不一定是二倍)
//2.遍历旧表的数据,重新计算在新表中的位置
//3.释放旧表
vector<Node*> newtables;
//size_t newsize = _tables.size() == 0 ? 19 : _tables.size() * 2;
size_t newsize = GetNextPrime(_tables.size());
newtables.resize(newsize);
for (size_t i = 0; i < _tables.size(); i++) {
//将旧表中的节点取下来重新计算在新表中的位置,并插入进去
Node* cur = _tables[i];
//遍历桶里面的元素
while (cur) {
Node* next = cur->_next;
size_t index = HashFunc(koft(cur->_data)) % newtables.size();
cur->_next = newtables[index];
newtables[index] = cur;
cur = next;
}
_tables[i] = nullptr;
}
_tables.swap(newtables);
}
size_t index = HashFunc(koft(data)) % _tables.size();
//先查找在不在表里
Node* cur = _tables[index];
while (cur) {
if (koft(cur->_data) == koft(data))
{
return make_pair(iterator(cur,this),false);
}
else {
cur = cur->_next;
}
}
//头插(尾差也可)
Node* newnode = new Node(data);
newnode->_next = _tables[index];
_tables[index] = newnode;
++_num;
return make_pair(iterator(newnode, this), true);
}
Node* Find(const K& key) {
size_t index = HashFunc(key) % _tables.size();
Node* cur = _tables[index];
while (cur) {
if (koft(cur->_data)==key ){
return cur;
}
else {
cur = cur->_next;
}
}
return nullptr;
}
bool Erase(const K& key) {
KeyOfT koft;
size_t index = HashFunc(key) % _tables.size();
Node* cur = _tables[index];
Node* prev = nullptr;
while (cur)
{
if (koft(cur->_data) == key) {
if (prev == nullptr) {
//表示要删的值在第一个节点
_tables[index] = cur->_next;
}else{
prev->_next = cur->_next;
}
delete cur;
return true;
}
else {
cur = cur->_next;
}
}
return false;
}
private:
vector<Node*> _tables;
size_t _num = 0;//记录表中存储的数据个数
};
void TestHashTable() {
HashTable<int, int, SetKeyOfT<int>> ht;
/* ht.Insert(4);
ht.Insert(14);
ht.Insert(24);
ht.Insert(5);
ht.Insert(15);
ht.Insert(25);
ht.Insert(6);
ht.Insert(16);
ht.Insert(26);
ht.Insert(36);
ht.Insert(33);
ht.Erase(4);
ht.Erase(14);*/
}
void TestHashTable2() {
HashTable<string, string, SetKeyOfT<string>> ht;
/*ht.Insert("sort");
ht.Insert("string");
ht.Insert("left");*/
}
}
HashMap
#pragma once
#include"HashTable.h"
#include<utility>
namespace bit
{
using std::pair;
using std::endl;
using std::make_pair;
template<class K,class V, class Hash = _Hash<K>>
class unordered_map
{
struct MapKofT
{
const K& operator()(const pair<K, V>& kv)
{
return kv.first;
}
};
public:
typedef typename HashTable<K, pair<K,V>, MapKofT, Hash>::iterator iterator;
iterator begin()
{
return _ht.begin();
}
iterator end()
{
return _ht.end();
}
pair<iterator,bool> insert(const pair<K, V>& kv) {
return _ht.Insert(kv);
}
V& operator[](const K& key)
{
pair<iterator,bool> ret = _ht.Insert(make_pair(key, V()));
return ret.first->second;
}
private:
HashTable<K, pair<K, V>, MapKofT,Hash> _ht;
};
void test_unorderedmap()
{
unordered_map<string, string> dict;
dict.insert(make_pair("sort", "排序"));
dict.insert(make_pair("left", "左边"));
dict.insert(make_pair("string", "字符串"));
dict["left"] = "hhh";
dict["end"] = "尾部";
auto it = dict.begin();
while (it != dict.end()) {
cout << it->first << ":"<<it->second<<endl;
++it;
}
}
}
HashSet
#pragma once
#include"HashTable.h"
#include<iostream>
namespace bit
{
using std::cout;
template<class K,class Hash = _Hash<K>>
class unordered_set
{
private:
struct SetKofT
{
const K& operator()(const K& k)
{
return k;
}
};
public:
typedef typename HashTable<K, K, SetKofT, Hash>::iterator iterator;
iterator begin()
{
return _ht.begin();
}
iterator end()
{
return _ht.end();
}
pair<iterator,bool> insert(const K& k) {
return _ht.Insert(k);
}
private:
HashTable<K, K, SetKofT,Hash> _ht;
};
void test_unorderedset()
{
unordered_set<int> s;
s.insert(1);
s.insert(5);
s.insert(4);
s.insert(2);
auto it = s.begin();
while (it != s.end()) {
cout << *it << " ";
++it;
}
}
}
BItSet
#pragma once
#include<vector>
#include<iostream>
namespace bit
{
using std::cout;
using std::endl;
class bitset
{
public:
bitset(size_t N)
{
_bits.resize(N / 32 + 1, 0);
_num = 0;
}
void set(size_t x)
{
size_t index = x / 32;//计算映射位置在第几个整型
size_t pos = x % 32;//算出x在整型第几个位
_bits[index] |= (1 << pos);//第pos个位置成1
}
void reset(size_t x)
{
size_t index = x / 32;//计算映射位置在第几个整型
size_t pos = x % 32;//算出x在整型第几个位
_bits[index] &= ~(1 << pos);//第pos个位置成1
}
bool test(size_t x) {
size_t index = x / 32;//计算映射位置在第几个整型
size_t pos = x % 32;//算出x在整型第几个位
return _bits[index] & (1 << pos);
}
private:
std::vector<int> _bits;
size_t _num;//映射存储多少个数据
};
void test_bitset()
{
bitset bs(100);
bs.set(99);
bs.set(98);
bs.set(97);
bs.set(5);
bs.reset(98);
for (size_t i = 0; i < 100; i++) {
cout << i << ":" << bs.test(i)<<endl;
}
}
}