简单实现C++ hashmap(包含iterator)

原理:原理很简单就是数组和链表,数组是用来散列的,链表主要用来存储的,链表的长度超过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;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值