原理:原理很简单就是数组和链表,数组是用来散列的,链表主要用来存储的,链表的长度超过8个就转为红黑树(没实现)。
直接上代码:
#include<iostream>
#include<string>
#include<unordered_map>
using namespace std;
#define LOADFACTOR 0.75
#define EXPANDFACTOR 2
template<class Key, class Value>
class Pair;
template<class Key, class Value>
class Node {
public:
Node *next_;
Key key_;
Value value_;
Node *pre_;
Node(Key key, Value value)
{
next_ = NULL;
key_ = key;
value_ = value;
pre_ = NULL;
}
~Node()
{
}
Node& operator=(const Node& node)
{
key_ = node.key_;
value_ = node.value_;
next_ = node.next_;
pre_ = node.pre_;
return *this;
}
};
template<class Key, class Value, class HashFun, class EqualKey>
class my_iterator;
template<class Key, class Value, class HashFun, class EqualKey>
class HashMap {
public:
typedef my_iterator<Key, Value, HashFun, EqualKey> iterator;
HashMap(int capacity)
:capacity_(capacity), size_(0), hash_(), equal_()
{
table_ = new Node<Key, Value> *[capacity_];
for (int i = 0; i < capacity_; i++)
{
table_[i] = NULL;
}
}
~HashMap()
{
for (int i = 0; i < capacity_; i++)
{
Node<Key, Value> *CurNode = table_[i];
while (CurNode)
{
Node<Key, Value>* tmp = CurNode;
CurNode = CurNode->next_;
delete tmp;
}
}
delete []table_;
}
//返回hashmap当前存储的元素个数size
int size()
{
return size_;
}
//返回hashmap的总容量
int capacity()
{
return capacity_;
}
//判断容器是否为空
bool empty()
{
return size_ == 0;
}
//插入
bool insert(const Key& key, const Value& value)
{
if (size_ >= (capacity_ * LOADFACTOR))
{
rehash(capacity_ * EXPANDFACTOR);
}
int index = hash_(key) % capacity_;
Node<Key, Value> *node = new Node<Key, Value>(key, value);
Node<Key, Value> *tmp = table_[index];
node->next_ = tmp;
node->pre_ = NULL;
if (tmp) {
tmp->pre_ = node;
}
table_[index] = node;
size_++;
return true;
}
void rehash(int capacity)
{
Node<Key, Value> **tmp_table = new Node<Key, Value> *[capacity];
for (int i = 0; i < capacity; i++)
{
tmp_table[i] = NULL;
}
for (int i = 0; i < capacity_; i++)
{
//size_ = 0;
if (table_[i] != NULL)
{
Node<Key, Value> *tmp_Node = table_[i];
while (tmp_Node)
{
insert1(tmp_Node->key_, tmp_Node->value_, tmp_table, capacity);
tmp_Node = tmp_Node->next_;
}
delete tmp_Node;
}
}
delete []table_;
table_ = tmp_table;
capacity_ = capacity;
}
void insert1(const Key& key, const Value& value, Node<Key, Value> **table, int capacity)
{
int index = hash_(key) % capacity;
Node<Key, Value> * node = new Node<Key, Value>(key, value);
node->next_ = table[index];
table[index] = node;
}
//删除
/*bool Delete(const Key& key)
{
//同过key值和hash函数确定存储在哪一个链表中,然后通过比对key值来确定删除的对象
int index = hash_(key) % capacity_;
Node<Key, Value> *node = table_[index];
while (node)
{
if (node->key_ == key)
{
if (node->pre_ == NULL)
{
table_[index] = node->next_;
}
else
{
node->pre_->next_ = node->next_;
}
size_--;
delete node;
return true;
}
node = node->next_;
}
throw exception("删除失败!");
return false;
}*/
//时间复杂度 O(1) 复杂版
iterator erase2(const iterator& it)
{
int index = hash_(it.cur_Node_->key_) % capacity_;
Node<Key, Value> *tmp = it.cur_Node_->next_;
if (it.cur_Node_->pre_ == NULL && it.cur_Node_->next_ != NULL)
{
Node<Key, Value> *tmp = it.cur_Node_->next_;
tmp->pre_ = NULL;
table_[index] = tmp;
delete it.cur_Node_;
size_--;
return iterator(this, tmp, table_);
}
else if (it.cur_Node_->pre_ == NULL && it.cur_Node_->next_ == NULL)
{
delete it.cur_Node_;
table_[index] = NULL;
for (int i = index + 1; i < capacity_; i++)
{
if (table_[i] != NULL)
{
Node<Key, Value> *tmp = table_[i];
size_--;
return iterator(this, tmp, table_);
}
}
size_--;
return iterator(this, NULL, table_);
}
else if (it.cur_Node_->pre_ != NULL && it.cur_Node_->next_ != NULL)
{
it.cur_Node_->pre_->next_ = it.cur_Node_->next_;
it.cur_Node_->next_->pre_ = it.cur_Node_->pre_;
Node<Key, Value> *tmp = it.cur_Node_->next_;
delete it.cur_Node_;
size_--;
return iterator(this, tmp, table_);
}
else if (it.cur_Node_->pre_ != NULL && it.cur_Node_->next_ == NULL)
{
it.cur_Node_->pre_->next_ = NULL;
delete it.cur_Node_;
for (int i = index + 1; i < capacity_; i++)
{
if (table_[i] != NULL)
{
Node<Key, Value> *tmp = table_[i];
size_--;
return iterator(this, tmp, table_);
}
}
size_--;
return iterator(this, NULL, table_);
}
return iterator(this, NULL, table_);
}
// 时间复杂度O(1) 简化版
iterator erase1(const iterator& it)
{
int index = hash_(it.cur_Node_->key_) % capacity_;
if (it.cur_Node_->pre_ == nullptr)
table_[index] = it.cur_Node_->next_;
else
it.cur_Node_->pre_->next_ = it.cur_Node_->next_;
--size_;
if (it.cur_Node_->next_) {
it.cur_Node_->next_->pre_ = it.cur_Node_->pre_;
auto * tmp = it.cur_Node_->next_;
delete it.cur_Node_;
return iterator(this, tmp, table_);
}
else
{
delete it.cur_Node_;
for (int i = index + 1; i < capacity_; i++)
{
if (table_[i] != NULL)
{
Node<Key, Value> *tmp = table_[i];
return iterator(this, tmp, table_);
}
}
return end();
}
}
//时间复杂度O(n)
iterator erase(const iterator& it)
{
int index = hash_(it.cur_Node_->key_) % capacity_;
Node<Key, Value> *node = table_[index];
while (node)
{ Node<Key, Value> *tmp = node->next_;
if (node->key_ == it.cur_Node_->key_)
{
if (node->pre_ == NULL && tmp != NULL)
{
tmp = node->next_;
tmp->pre_ = NULL;
table_[index] = tmp;
delete node;
size_--;
return iterator(this, tmp, table_);
}
else if (node->pre_ == NULL && tmp == NULL)
{
delete node;
table_[index] = NULL;
for (int i = index + 1; i < capacity_; i++)
{
if (table_[i] != NULL)
{
tmp = table_[i];
size_--;
return iterator(this, tmp, table_);
}
}
size_--;
return iterator(this, tmp, table_);
}
else if(node->pre_ != NULL && tmp != NULL)
{
node->pre_->next_ = tmp;
node->next_->pre_ = node->pre_;
delete node;
size_--;
return iterator(this, tmp, table_);
}
else if (node->pre_ != NULL && tmp == NULL)
{
node->pre_->next_ = NULL;
delete node;
for (int i = index + 1; i < capacity_; i++)
{
if (table_[i] != NULL)
{
tmp = table_[i];
size_--;
return iterator(this, tmp, table_);
}
}
}
}
node = node->next_;
}
return iterator(this, NULL, table_);
}
//查找
/*Value& find(const Key& key)
{
int index = hash_(key) % capacity_;
if (table_[index] == NULL)
{
throw exception("没有找到!");
}
else
{
Node<Key, Value> *node = table_[index];
while (node)
{
if (node->key_ == key)
{
return node->value_;
}
node = node->next_;
}
throw exception("没有找到!");
}
}*/
iterator find1(const Key& key)
{
int index = hash_(key) % capacity_;
Node<Key, Value> *node = table_[index];
while (node)
{
if (node->key_ == key)
{
return iterator(this, node, table_);
}
node = node->next_;
}
return iterator(this, NULL, table_);
}
//rehash 当前容器中存储的元素已经达到的阀值,就需要将容器的容量扩大为原来的两倍
/*void rehash(int capacity)
{
Node<Key, Value> **tmp_table = new Node<Key, Value> *[capacity];
for (int i = 0; i < capacity; i++)
{
tmp_table[i] = NULL;
}
for (int i = 0; i < capacity_; i++)
{
if (table_[i] != NULL)
{
Node<Key, Value> *tmp_Node = table_[i];
while (tmp_Node)
{
insert1(tmp_Node, tmp_table, capacity);
tmp_Node = tmp_Node->next_;
}
delete tmp_Node;
}
}
delete []table_;
table_ = tmp_table;
capacity_ = capacity;
}
void insert1(Node<Key, Value> *node, Node<Key, Value> **table, int capacity)
{
int index = hash_(node->key_) % capacity;
node->next_ = table[index];
node->pre_ = NULL;
table[index] = node;
}*/
//reserve
void reserve(int capacity)
{
rehash(capacity);
}
//begin
iterator begin()
{
for (int i = 0; i < capacity_; i++)
{
Node<Key, Value> *node = table_[i];
if (node != NULL)
{
return iterator(this, node, table_);
}
}
return iterator(this, NULL, table_);
}
//end
iterator end()
{
return iterator(this, NULL, table_);
}
Value& operator[](const Key& key)
{
;
if (find1(key).cur_Node_ != NULL)
{
return (*find1(key));
}
else
{
//Value value = new Value();
insert(key,Value());
return (*find1(key));
}
}
friend class my_iterator<Key, Value, HashFun, EqualKey>;
private:
HashFun hash_; //hash函数
EqualKey equal_; //比较函数
Node<Key, Value> **table_; //创建的哈希表
int size_; //hashmap存储元素的个数
int capacity_; //hashmap容量
};
//实现迭代器
template<class Key, class Value>
class Node;
template<class Key, class Value, class HashFun, class EqualKey>
class HashMap;
template<class Key, class Value, class HashFun, class EqualKey>
class my_iterator
{
public:
my_iterator(HashMap<Key, Value, HashFun, EqualKey> *hashmap, Node<Key, Value> *node, Node<Key, Value> **table)
:hashmap_(hashmap), cur_Node_(node), table_(table)
{
}
~my_iterator()
{
}
Value& operator*()const
{
return cur_Node_->value_;
}
Value* operator->()const
{
return &(operator*());
}
bool operator ==(const my_iterator& it)
{
return cur_Node_ == it.cur_Node_;
}
bool operator!=(const my_iterator& it)
{
return cur_Node_ != it.cur_Node_;
}
my_iterator& operator++()
{
if (cur_Node_->next_ != NULL)
{
cur_Node_ = cur_Node_->next_;
}
else
{
int CapacityTmp = hashmap_->capacity_;
int index = hashmap_->hash_(cur_Node_->key_) % CapacityTmp;
int tmpindex = index + 1;
Node<Key, Value> * tmp = NULL;
while (tmpindex < hashmap_->capacity_)
{
tmp = table_[tmpindex];
if (tmp == NULL)
{
++tmpindex;
}
else
{
break;
}
}
if (tmp != NULL)
{
cur_Node_ = tmp;
index = tmpindex;
return *this;
}
else
{
hashmap_ = hashmap_->end().hashmap_;
cur_Node_ = NULL;
table_ = hashmap_->end().table_;
return *this;
}
}
return *this;
}
my_iterator& operator--()
{
if (cur_Node_->pre_ != NULL)
{
cur_Node_ = cur_Node_->pre_;
}
if (!cur_Node_)
{
int index = hashmap_->hash_(cur_Node_->key_) % hashmap_->capacity_;
for (int i = index - 1; i >= 0; i--)
{
if (hashmap_->table_[index] != NULL)
{
cur_Node_ = hashmap_->table_[index];
}
}
}
return *this;
}
my_iterator& operator--(int)
{
my_iterator tmp = *this;
return --*this;
}
my_iterator& operator++(int)
{
my_iterator tmp = *this;
return ++*this;
}
friend class Node<Key, Value>;
friend class HashMap<Key, Value, HashFun, EqualKey>;
private:
HashMap<Key, Value, HashFun, EqualKey> *hashmap_;
Node<Key, Value> *cur_Node_; //当前所指的结点
Node<Key, Value> **table_; //哈希表
};
//hash函数
class HashFun
{
public:
int operator()(const string& key)
{
int hash = 0;
for (int i = 0; i < key.length(); i++)
{
hash = (hash << 7) ^ key[i];
}
return (hash & 0x7FFFFFFF);
}
};
//比较函数
class EqualKey
{
public:
bool operator()(const string& s1, const string& s2)
{
if (s1.compare(s2) == 0)
{
return true;
}
else
{
false;
}
}
};
以上是完全的代码,下面是测试代码
int main()
{
/*
try {
HashMap<string, string, HashFun, EqualKey> hashmap(16);
hashmap.insert("hello", "world");
hashmap.insert("1", "zhang");
hashmap.insert("1", "cool");
hashmap.insert("2", "wang");
hashmap.insert("3", "li");
hashmap.insert("4", "haha");
cout << "当前hashmap的容量是:" << hashmap.capacity() << endl;
cout << "插入5个元素之后:" << endl;
cout << "key值为hello的元素:" << hashmap.find("hello") << endl;
cout << "key值为1的元素:" << hashmap.find("1") << endl;
cout << "key值为2的元素:" << hashmap.find("2") << endl;
cout << "key值为3的元素:" << hashmap.find("3") << endl;
cout << "key值为4的元素:" << hashmap.find("4") << endl;
hashmap["4"] = "mark";
cout << "key值为4的元素:" << hashmap.find("4") << endl;
cout << "当前hashmapz中存储的元素个数是:" << hashmap.size() << endl;
cout << "当前hashmap的容量是:" << hashmap.capacity() << endl;
hashmap.Delete("2");
cout << "删除key值为2的元素后查找key为2的值:";
cout << hashmap.find("2") << endl;
}
catch (exception& e)
{
cout << e.what() << endl;
}
cout << "*********************scend***************************" << endl;
try {
HashMap<string, int, HashFun, EqualKey> hashmap1(16);
hashmap1.insert("hello", 100);
hashmap1.insert("0", 1);
hashmap1.insert("1", 2);
hashmap1.insert("2", 3);
hashmap1.insert("3", 4);
hashmap1.insert("4", 5);
cout << "当前hashmap的容量是:" << hashmap1.capacity() << endl;
cout << "插入5个元素之后:" << endl;
//cout << "key值为hello的元素:" << hashmap1.find("hello") << endl;
cout << "key值为1的元素:" << hashmap1.find("1") << endl;
cout << "key值为2的元素:" << hashmap1.find("2") << endl;
cout << "key值为3的元素:" << hashmap1.find("3") << endl;
cout << "key值为4的元素:" << hashmap1.find("4") << endl;
cout << "key值为0的元素:" << hashmap1.find("0") << endl;
hashmap1["4"] = 40;
cout << "key值为4的元素:" << hashmap1.find("4") << endl;
cout << "当前hashmapz中存储的元素个数是:" << hashmap1.size() << endl;
cout << "当前hashmap的容量是:" << hashmap1.capacity() << endl;
hashmap1.Delete("hello");
cout << "删除key值为hello的元素后:";
cout << "此时容器中的元素个数是:" << hashmap1.size() << endl;
cout << hashmap1.find("hello") << endl;
}
catch (exception& e)
{
cout << e.what() << endl;
}
*/
/*
try {
HashMap<string, string, HashFun, EqualKey> hashmap(8);
hashmap.insert("hello", "hello");
hashmap.insert("9", "world");
hashmap.insert("1", "zhang");
hashmap.insert("5", "cool");
hashmap.insert("8", "wo");
hashmap.insert("7", "7");
hashmap.insert("2", "wang");
cout << "插入七个元素后hashmap的容量是:" << hashmap.capacity() << endl;
cout << "当前hashmapz中存储的元素个数是:" << hashmap.size() << endl;
hashmap.insert("3", "li");
hashmap.insert("4", "haha");
hashmap.insert("10", "nihao");
cout << "在插入三个元素后hashmap的容量是:" << hashmap.capacity() << endl;
cout << "当前hashmap中存储的元素个数是:" << hashmap.size() << endl;
cout << "key值为1的元素:" << hashmap.find("1") << endl;
cout << "key值为2的元素:" << hashmap.find("2") << endl;
cout << "key值为3的元素:" << hashmap.find("3") << endl;
cout << "key值为4的元素:" << hashmap.find("4") << endl;
cout << "key值为5的元素:" << hashmap.find("5") << endl;
cout << "key值为10的元素:" << hashmap.find("10") << endl;
cout << "key值为8的元素:" << hashmap.find("8") << endl;
cout << "key值为9的元素:" << hashmap.find("9") << endl;
cout << "key值为hello的元素:" << hashmap.find("hello") << endl;
cout << "key值为7的元素:" << hashmap.find("7") << endl;
cout << "****************************将容器扩容为8************************************" << endl;
hashmap.reserve(4);
cout << "key值为1的元素:" << hashmap.find("1") << endl;
cout << "key值为2的元素:" << hashmap.find("2") << endl;
cout << "key值为3的元素:" << hashmap.find("3") << endl;
cout << "key值为4的元素:" << hashmap.find("4") << endl;
cout << "key值为5的元素:" << hashmap.find("5") << endl;
cout << "key值为10的元素:" << hashmap.find("10") << endl;
cout << "key值为8的元素:" << hashmap.find("8") << endl;
cout << "key值为9的元素:" << hashmap.find("9") << endl;
cout << "key值为hello的元素:" << hashmap.find("hello") << endl;
cout << "key值为7的元素:" << hashmap.find("7") << endl;
cout << "此时容器是否为空:" << hashmap.empty() << endl;
cout << "当前hashmap中存储的元素个数是:" << hashmap.size() << endl;
cout << "当前hashmap的容量是:" << hashmap.capacity() << endl;
cout << "key值为9的元素:" << hashmap.find("9") << endl;
hashmap.Delete("7");
//cout << "删除key值为7的元素后查找key值为7的元素的结果是:" << hashmap.find("7") << endl;
}
catch (exception& e)
{
cout << e.what() << endl;
}*/
/*
try
{
HashMap<string, string, HashFun, EqualKey> hashmap(4);
hashmap.insert("hello", "hello");
hashmap.insert("9", "world");
hashmap.insert("1", "zhang");
hashmap.insert("5", "cool");
hashmap.insert("8", "wo");
hashmap.insert("7", "7");
hashmap.insert("2", "wang");
cout << "通过迭代器打印hashmap中的元素:";
HashMap<string, string, HashFun, EqualKey>::iterator it = hashmap.begin();
for (it; it != hashmap.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
cout << "插入七个元素后hashmap的容量是:" << hashmap.capacity() << endl;
cout << "当前hashmapz中存储的元素个数是:" << hashmap.size() << endl;
hashmap.insert("3", "li");
hashmap.insert("4", "haha");
hashmap.insert("10", "nihao");
cout << "在插入三个元素后hashmap的容量是:" << hashmap.capacity() << endl;
cout << "当前hashmap中存储的元素个数是:" << hashmap.size() << endl;
//cout << "key值为20的默认value是:" << hashmap["20"] << endl;
//hashmap.Delete("hello");
cout << "通过迭代器打印hashmap中的元素:";
it = hashmap.begin();
for (it; it != hashmap.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
it = hashmap.begin();
hashmap.erase1(it);
cout << "erase后" << endl;
cout << "通过迭代器打印hashmap中的元素:";
it = hashmap.begin();
for (it; it != hashmap.end(); it++)
{
cout << *it << " ";
}
cout << endl;
it = hashmap.begin();
for (int i = 0; i < 5; i++)
{
it++;
}
cout << "--it的值是:" << *(--it) << endl;
it = hashmap.begin();
for (int i = 0; i < 5; i++)
{
it++;
}
cout << "it--的值是:" << *(it--) << endl;
//cout << "key值为3的元素是:" << hashmap.find("3") << endl;
cout << "key值为4的元素是:" << *(hashmap.find1("4")) << endl;
//cout << "key值为hello的元素是:" << *(hashmap.find1("hello")) << endl;
cout << "当前hashmap中存储的元素个数是:" << hashmap.size() << endl;
//cout << hashmap["20"] << endl;;
it = hashmap.begin();
for (it; it != hashmap.end();)
{
it = hashmap.erase2(it);
}
cout << "当前hashmap中存储的元素个数是:" << hashmap.size() << endl;
}
catch (exception& e)
{
cout << e.what() << endl;
}*/
HashMap<string, string, HashFun, EqualKey> hashmap(1);
hashmap.insert("hello", "hello");
hashmap.insert("9", "world");
hashmap.insert("1", "zhang");
hashmap.insert("5", "cool");
cout << "通过迭代器打印:";
HashMap<string, string, HashFun, EqualKey>::iterator it = hashmap.begin();
for (it; it != hashmap.end(); it++)
{
cout << *it << " ";
}
return 0;
}